对于同一个调用以及来自同一浏览器的相同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
注意:
Access-Control-Request-Headers:cache-control,if-modified-since,pragma,x-requested-with
Access-Control-Request-Method:GET
,而用户界面2位于不同的Visual Studio Solution
。我相信这不是原因,但我可能是错的。修改
正如@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项目的调用,尽管请求标题不同。
答案 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
函数中的标题
delete $httpProvider.defaults.headers.common['X-Requested-With'];
我认为关键是OPTIONS
请求的请求标头
访问控制请求报头:缓存控制,如果改性-因为,编译指示,的的x请求-以强>
如果您希望您的API能够正确处理跨源请求,则应该正确回应转发前OPTIONS
次请求。