为什么同一个ajax调用有不同的请求标头?

时间:2017-05-05 00:48:53

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

对于同一个调用以及来自同一浏览器的相同JS代码,请求标头如何不同?

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

AngularJs 1.X

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

但是,对于一个呼叫成功而另一个呼叫失败,则说明以下错误。

  

对预检请求的响应没有通过访问控制检查:否'访问控制 - 允许 - 来源'标头出现在请求的资源上。

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

请求成功通话的标头 - AngularJS v1.6.4

$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);
          }
         );

成功调用的响应标头

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

请求未能通话的标头 - AngularJS v1.2.17

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

未通过的呼叫的响应标头

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

注意:

  1. 我的用户界面和API位于同一Access-Control-Request-Headers:cache-control,if-modified-since,pragma,x-requested-with Access-Control-Request-Method:GET ,而用户界面2位于不同的Visual Studio Solution。我相信这不是原因,但我可能是错的。
  2. 我在两个UI项目中都有不同的AngularJS版本。这可能是个原因吗?
  3. 修改

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

    Solution

    并在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); } } 注册了此WebApiConfig。

    Global.asax

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

2 个答案:

答案 0 :(得分:2)

  

对于失败的呼叫 - 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)

答案 1 :(得分:1)

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

较早版本的Angular添加了x-requested-with标头。这已经被取消了。此标头会导致您的CORS请求为non-simple,从而触发行前OPTIONS请求。看起来你的后端没有设置来处理这些请求。

您可以通过删除config函数中的标题

,在较旧的Angular版本中解决此问题
delete $httpProvider.defaults.headers.common['X-Requested-With'];

我认为关键是OPTIONS请求的请求标头

  

访问控制请求报头:缓存控制,如果改性-因为,编译指示,的的x请求-以

如果您希望您的API能够正确处理跨源请求,则应该正确回应转发前OPTIONS次请求。