Why there are different request headers for same ajax call?

▼魔方 西西 提交于 2019-12-24 07:25:50

问题


How could request headers be different for the same call and for the same JS code from the same browser?

I have one web API project and I am calling a method in this API from two different projects (CORS calls), using $http.get method of AngularJs 1.X.

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

This is the same code that is being used from both front-end UIs to call the API.

However, for one the call succeeds and for the other it fails, stating below error.

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Upon observation, I have found a difference in request headers for both the calls.

Requests Header for call that succeeds - 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

Response Header for the call that succeeds

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

Request Header for call that fails - 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

Response header for call that fails

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

These are the two request headers that are additional in the second call.

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

Note:

  1. My UI one and API are in the same Visual Studio Solution, while UI two is in a different Solution. I believe this could not be the reason but I could be wrong.
  2. I have different AngularJS versions in both the UI projects. Could this be a possible reason?

EDIT

As suggested by @Phil, I updated my backend API to handle the preflight requests coming from my 2nd UI project.

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

And registered this WebApiConfig in Global.asax.

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

And it started handling the calls from 2nd UI project as well, though the request headers were different.


回答1:


For call that fails - AngularJS v1.2.17

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

This to me looks like the browser is doing a CORS pre-flight check to get permission to include non-standard headers. Look in the app to see why it is adding those non-standard headers.

Versions of AngularJS before v1.1.1 used to include x-request-with as a default and cause this problem.

Check for a config block that changes $httpProvider.defaults.

For the list of allowed headers that won't trigger a pre-flight request, see MDN HTTP Reference - Access_control_CORS (Simple Requests)




回答2:


Here's my guess...

Older versions of Angular added the x-requested-with header. This has since been dropped. This header causes your CORS request to be non-simple which triggers a pre-flight OPTIONS request. Looks like your backend isn't set up to handle these requests.

You can work around this in the older Angular version by removing the header in your config function

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

The key was this line in what I assume is the request headers for the OPTIONS request

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


If you want your API to work correctly with cross-origin requests, it should respond correctly to pre-flight OPTIONS requests.



来源:https://stackoverflow.com/questions/43794831/why-there-are-different-request-headers-for-same-ajax-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!