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

Posted

技术标签:

【中文标题】定义 Content-Type 时跨域 jQuery AJAX 失败【英文标题】:Cross-domain jQuery AJAX fails when defining Content-Type 【发布时间】:2016-01-26 14:43:46 【问题描述】:

我有一个 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】:

当我突然明白问题出在 AJAX 调用中时,我花了很多时间与 WebAPI CORS 进行“战斗”。此请求执行成功:

$.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 并拒绝请求。

This *** question 与这个问题直接相关,解释了什么是“预检”请求以及为什么浏览器需要发送它。

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

如果您需要为您的请求指定自定义标头或Content-Type,您可以实现一个允许预检请求的特殊处理程序。 This *** article 描述了如何做到这一点。

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

【讨论】:

以上是关于定义 Content-Type 时跨域 jQuery AJAX 失败的主要内容,如果未能解决你的问题,请参考以下文章

jQuery ajax调接口时跨域

请求接口时跨域问题,前端解决方法

使用vue-cli开发时跨域问题

如何解决IE8下Ajax调用时跨域的问题

用webpack-dev-server开发时代理,决解开发时跨域问题

用webpack-dev-server开发时代理,决解开发时跨域问题