定义内容类型时,跨域jQuery AJAX失败



我有一个ASP.NET WebAPI客户端,它具有以下配置,允许任何跨域POSTGET调用:

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-urlencodedmultipart/form-datatext/plain以外的任何内容都将触发浏览器向服务器发送飞行前OPTIONS请求。

浏览器正在对请求进行预处理,以查找CORS标头,并发现服务器是否允许跨域请求,并且发出真正的请求是安全的。如果请求是可接受的,那么它将发送真正的请求。

浏览器发送的飞行前请求是:

  • HTTP方法不是GETPOSTHEAD
  • 或者如果Content-Type不是application/x-www-form-urlencodedmultipart/form-datatext/plain
  • 或者如果设置了任何自定义HTTP头

因此,Chrome发送OPTIONS"飞行前"请求。由于我在服务器上只允许POSTGET请求,浏览器认为这是违反CORS的行为,并拒绝了请求。

这个StackOverflow问题与这个问题直接相关,它解释了什么是"飞行前"请求,以及为什么浏览器需要发送它

解决方案和问题原因一样简单——不要在跨域AJAX调用中指定ContentType。

如果您需要为请求指定自定义标头或Content-Type,您可以实现一个特殊处理程序,该处理程序将允许飞行前请求。这篇StackOverflow文章描述了如何做到这一点。

我希望它能帮助人们节省时间。

相关内容

  • 没有找到相关文章

最新更新