为什么同一ajax调用有不同的请求标头? [英] Why there are different request headers for same ajax call?
问题描述
对于来自同一浏览器的同一调用和同一JS代码,请求标头如何不同?
How could request headers be different for the same call and for the same JS code from the same browser?
我有一个Web API项目,并且正在从两个不同的项目中调用此API中的方法(CORS调用),使用 AngularJs 1.X
的 $ http.get
方法.
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);
}
);
这是两个前端UI用来调用API的相同代码.
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.
对预检请求的响应未通过访问控制检查:所请求的资源上没有'Access-Control-Allow-Origin'标头.
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.
请求成功调用的标题-AngularJS v1.6.4
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
成功呼叫的响应标题
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
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
失败的呼叫响应头
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
注意:
- 我的UI一和API位于相同的
Visual Studio解决方案
中,而用户二则位于不同的解决方案
中.我相信这可能不是原因,但我可能是错的. - 我在两个UI项目中都有不同的AngularJS版本.这可能是一个可能的原因吗?
- My UI one and API are in the same
Visual Studio Solution
, while UI two is in a differentSolution
. I believe this could not be the reason but I could be wrong. - I have different AngularJS versions in both the UI projects. Could this be a possible reason?
编辑
按照@Phil的建议,我更新了后端API以处理来自第二个UI项目的预检请求.
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);
}
}
并在 Global.asax
中注册此WebApiConfig.
And registered this WebApiConfig in Global.asax
.
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
}
尽管请求标头不同,它也开始处理第二个UI项目的调用.
And it started handling the calls from 2nd UI project as well, though the request headers were different.
推荐答案
对于失败的呼叫-AngularJS v1.2.17
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
在我看来,这似乎是浏览器正在执行 CORS飞行前检查以获取包含非标准标头的权限.在应用程序中查找,以了解为什么要添加那些非标准标头.
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.
v1.1.1之前的AngularJS版本以前默认包含 x-request-with
并导致此问题.
Versions of AngularJS before v1.1.1 used to include x-request-with
as a default and cause this problem.
检查更改 $ httpProvider.defaults
的配置块.
有关不会触发飞行前请求的允许标头列表,请参见 MDN HTTP参考-Access_control_CORS(简单请求)
For the list of allowed headers that won't trigger a pre-flight request, see MDN HTTP Reference - Access_control_CORS (Simple Requests)
这篇关于为什么同一ajax调用有不同的请求标头?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!