【问题标题】:Why there are different request headers for same ajax call?为什么同一个ajax调用有不同的请求头?
【发布时间】:2017-10-03 08:07:26
【问题描述】:

对于同一个调用和来自同一个浏览器的同一个 JS 代码,请求头怎么可能不同?

我有一个 Web API 项目,我正在使用 AngularJs 1.X$http.get 方法从两个不同的项目 (CORS calls) 调用此 API 中的一个方法。

$http.get("http://local.api:9002/api/default/get")
    .then(function success(response, status, headers, config) {
             console.info(response);
          },
          function error(response, status, headers, config) {
             console.info(response);
          }
         );

这与两个前端 UI 中用于调用 API 的代码相同。

但是,一个调用成功,另一个调用失败,说明以下错误。

对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。

经过观察,我发现两个调用的请求标头有所不同。

成功调用的请求标头 - AngularJS v1.6.4

Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Connection:keep-alive
Host:local.api:9002
Origin:http://local.ui.one:9001
Referer:http://local.ui.one:9001/
User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36

成功调用的响应标头

Access-Control-Allow-Origin:http://local.ui.one:9001
Cache-Control:no-cache
Content-Length:19
Content-Type:application/json; charset=utf-8
Date:Fri, 05 May 2017 01:05:05 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/7.5
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET

调用失败的请求标头 - AngularJS v1.2.17

Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Access-Control-Request-Headers:cache-control,if-modified-since,pragma,x-requested-with
Access-Control-Request-Method:GET
Connection:keep-alive
Host:local.api:9002
Origin:http://local.ui.two:9003
Referer:http://local.ui.two:9003/
User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36

调用失败的响应标头

Cache-Control:no-cache
Content-Length:113
Content-Type:application/json; charset=utf-8
Date:Fri, 05 May 2017 01:22:14 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/7.5
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET

这是第二次调用中附加的两个请求标头。

Access-Control-Request-Headers:cache-control,if-modified-since,pragma,x-requested-with
Access-Control-Request-Method:GET

注意:

  1. 我的 UI 1 和 API 位于同一个 Visual Studio Solution,而 UI 2 位于不同的 Solution。我相信这不是原因,但我可能是错的。
  2. 我在两个 UI 项目中都有不同的 AngularJS 版本。这可能是一个原因吗?

编辑

按照@Phil 的建议,我更新了后端 API 以处理来自我的第二个 UI 项目的预检请求。

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        //Some API routes here...

        var enableCorsAttribute = new EnableCorsAttribute(
            // Comma separated whitelist of allowed domains, notice no slash ('/') at the end of domain
            "http://local.ui.two:9003,http://local.ui.one:9001", 
            // Allowed Custom Headers
            "Origin, X-Requested-With, Content-Type, Accept, Authorization, Cache-Control, If-Modified-Since, Pragma",
            // Allowed methods
            "GET, PUT, POST, DELETE, OPTIONS"
        );

        config.EnableCors(enableCorsAttribute);
    }
}

并在Global.asax注册了这个WebApiConfig。

protected void Application_Start()
{
    GlobalConfiguration.Configure(WebApiConfig.Register);
}

它也开始处理来自第二个 UI 项目的调用,尽管请求标头不同。

【问题讨论】:

  • I have different AngularJS versions in both the UI projects. Could this be a possible reason? 是的。不要那样做:)
  • @Phix,感谢您的快速回复。然而,第二个项目是一个现有的项目,升级 AngularJS 版本并不划算。不过,我总是可以在我的第一个项目中降级版本。至少我可以试一试。
  • @Phix,我尝试将第二个项目升级到 Angular JS v1.6.4 并将第一个项目降级到 Angular JS v1.2.17。结果是一样的。我相信这不是 Angular JS 版本。
  • 在注释 #1 中,“解决方案” 是什么意思?错误消息是说您的服务器没有响应 Access-Control-Allow-Origin 响应标头
  • 你为什么要输入这些?请复制/粘贴

标签: angularjs ajax asp.net-web-api2 request-headers


【解决方案1】:

对于失败的调用 - AngularJS v1.2.17

Access-Control-Request-Headers:cache-control,if-modified-since,pragma,x-requested-with
Access-Control-Request-Method:GET

在我看来,浏览器正在执行CORS pre-flight check 以获得包含非标准标头的权限。在应用程序中查看为什么要添加这些非标准标头。

在 v1.1.1 之前的 AngularJS 版本曾经默认包含 x-request-with 并导致此问题。

检查更改 $httpProvider.defaults 的配置块。

有关不会触发飞行前请求的允许标头列表,请参阅MDN HTTP Reference - Access_control_CORS (Simple Requests)

【讨论】:

  • 让我感到困惑的是,OP 说他们使用 Angular 1.2.17 作为 older 版本:/
  • @Phil 我同意。我认为该应用正在添加x-requested-with 和其他有问题的标题。
  • @Phil 和 georgeawg 你们都是天才!事实上,在配置中添加这些标题的应用程序。感谢您的帮助!
  • 我从来没有想过会有代码故意添加这个标题。很好的演绎!
【解决方案2】:

这是我的猜测......

旧版本的 Angular 添加了 x-requested-with 标头。这已经被放弃了。此标头导致您的 CORS 请求为 non-simple,这会触发飞行前 OPTIONS 请求。您的后端似乎未设置为处理这些请求。

您可以在旧 Angular 版本中通过删除 config 函数中的标头来解决此问题

delete $httpProvider.defaults.headers.common['X-Requested-With'];

关键是我假设的这一行是OPTIONS 请求的请求标头

Access-Control-Request-Headers:cache-control,if-modified-since,pragma,x-requested-with


如果您希望您的 API 正确处理跨域请求,它应该正确响应 pre-flight OPTIONS 请求。

【讨论】:

  • 这两个请求方法都是 HTTP get 方法。如果这就是你的意思。我已经尝试为失败的调用升级 AngularJS 版本,但它给出相同的结果仍然失败。还尝试了另一种方法,为成功的调用降级 AngularJS 版本并且没有问题。所以我相信不是 AngularJS 版本导致了这个问题。
  • 但我会尝试一下。
  • 是的,确实是OPTIONS。我正在查看网络选项卡,那里显示获取请求。但控制台显示 OPTIONS。
  • @DevrajGadhavi 还确保您没有任何代码添加该标头。我会在 UI #2 中对您的代码进行不区分大小写的搜索
  • @DevrajGadhavi 这确实是我的意思:)
猜你喜欢
  • 2011-03-10
  • 1970-01-01
  • 2020-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-03
  • 2017-04-17
  • 2011-01-08
相关资源
最近更新 更多