我有一个ASP.NET WebAPI客户端,它具有以下配置,允许任何跨域POST
和GET
调用:
public static void Register(HttpConfiguration config)
{
config.EnableCors(new EnableCorsAttribute("*", "*", "GET,POST"));
// other unrelated configurations
}
我对我的WebAPI应用程序进行了AJAX调用,所有调用都失败了,控制台中出现了CORS阻止消息。
以下AJAX请求失败:
$.ajax({
url: "myserver:8081/User/Get",
data: {
"Id": 12
},
type: "POST",
dataType: "json",
contentType: "application/json; encoding=utf-8"
});
为什么会发生这种情况,如何解决?
我花了很多时间与WebAPI CORS"斗争",突然我明白问题出在AJAX调用中。此请求成功执行:
$.ajax({
url: "myserver:8081/User/Get",
data: {
"Id": 12
},
type: "POST",
dataType: "json",
// contentType: "application/json; encoding=utf-8"
});
根据jQuery.ajax() documentation
,
对于跨域请求,将内容类型设置为
application/x-www-form-urlencoded
、multipart/form-data
或text/plain
以外的任何内容都将触发浏览器向服务器发送飞行前OPTIONS请求。
浏览器正在对请求进行预处理,以查找CORS标头,并发现服务器是否允许跨域请求,并且发出真正的请求是安全的。如果请求是可接受的,那么它将发送真正的请求。
浏览器发送的飞行前请求是:
- HTTP方法不是
GET
、POST
或HEAD
- 或者如果
Content-Type
不是application/x-www-form-urlencoded
、multipart/form-data
或text/plain
- 或者如果设置了任何自定义HTTP头
因此,Chrome发送OPTIONS
"飞行前"请求。由于我在服务器上只允许POST
和GET
请求,浏览器认为这是违反CORS的行为,并拒绝了请求。
这个StackOverflow问题与这个问题直接相关,它解释了什么是"飞行前"请求,以及为什么浏览器需要发送它
解决方案和问题原因一样简单——不要在跨域AJAX调用中指定ContentType。
如果您需要为请求指定自定义标头或Content-Type
,您可以实现一个特殊处理程序,该处理程序将允许飞行前请求。这篇StackOverflow文章描述了如何做到这一点。
我希望它能帮助人们节省时间。