定义Content-Type时,跨域jQuery AJAX失败

时间:2015-10-27 09:09:25

标签: jquery ajax cross-domain cors asp.net-web-api2

我有一个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"
});

为什么会发生这种情况以及如何解决这个问题?

1 个答案:

答案 0 :(得分:4)

我花了很多时间与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请求。 / p>

浏览器预检查询CORS标头的请求,并发现服务器是否允许跨域请求并确保实际请求是安全的。如果请求是可接受的,它将发送实际请求。

浏览器发送的预检请求是:

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

因此,Chrome会发送OPTIONS“预检”请求。只要我在服务器上只允许POSTGET请求,浏览器就认为它是CORS违规并拒绝请求。

This StackOverflow question与此问题直接相关,并解释了什么是“预检”请求以及浏览器为何需要发送该请求。

解决方案就像问题原因一样简单 - 不要在跨域AJAX调用中指定Content-Type。

如果您需要为请求指定自定义标头或Content-Type,则可以实施一个允许预检请求的specal处理程序。 This StackOverflow article介绍了如何执行此操作。

我希望它可以帮助别人节省时间。