如何在不调用 Chrome 的 CORS 预检请求的情况下指定 `application/json` Content-Type?

Posted

技术标签:

【中文标题】如何在不调用 Chrome 的 CORS 预检请求的情况下指定 `application/json` Content-Type?【英文标题】:How to specify `application/json` Content-Type without invoking Chrome's CORS preflight request? 【发布时间】:2019-11-10 17:22:47 【问题描述】:

根据 fetch 规范,只要指定 Content-Type 是“application/x-www-form-urlencoded”、“multipart/form-data”或“text/plain”之一如果满足其他条件,则 POST 请求不应导致预检请求。然而,在实践中,我很难以一种不会导致 OPTIONS 请求进行预检检查的方式指定要获取的多个标头。

前 1 个。

fetch("https://differentsubodmain.example.com/api/resource", 
    headers: 
        "Content-Type": "text/plain, application/json",
        Accept: "application/json"
    ,
    method: "POST",
    body: JSON.stringify()
)

前 2 个。

var myHeaders = new Headers();
myHeaders.append('Accept', 'application/json');
myHeaders.append('Content-Type', 'text/plain');
myHeaders.append('Content-Type', 'application/json');

fetch("https://differentsubodmain.example.com/api/resource", 
    headers: myHeaders,
    method: "POST",
    body: JSON.stringify()
)

前 3.

fetch("https://differentsubodmain.example.com/api/resource", 
    headers: [
        ["Content-Type", "application/json"],
        ["Content-Type", "text/plain"],
        ["Accept", "application/json"]
    ],
    method: "POST",
    body: JSON.stringify()
    )

这些示例都没有在没有预检请求的情况下成功请求,但仅使用 "Content-Type": "text/plain" 指定任何一个似乎都可以正常工作。但是,example here 显示在请求中指定了两者,并建议它不应该导致预检。这只是不同浏览器实现的问题还是我遗漏了什么?

【问题讨论】:

标题是一个对象而不是示例中的数组数组是否重要?规范说这是一个列表,而不是对象。 这两种方式似乎都可以正常工作,但在 CORS 预检要求方面似乎都没有给我们回旋余地。 这能回答你的问题吗? Why is there no preflight in CORS for POST requests with standard content-type 【参考方案1】:

看来我可能没有仔细阅读该参考资料。以下是重要的摘录。

警告。这故意不使用提取 MIME 类型,因为该算法相当宽容,并且不希望服务器实现它。

如果使用提取 MIME 类型,则以下请求不会导致 CORS 预检,服务器上的简单解析器可能会将请求正文视为 JSON

看起来我们在很大程度上受限于 mime 类型 application/x-www-form-urlencodedmultipart/form-datatext/plain,以避免对 CORS 的预检请求。

参考:

https://fetch.spec.whatwg.org/#example-cors-safelisted-request-header-content-type

【讨论】:

以上是关于如何在不调用 Chrome 的 CORS 预检请求的情况下指定 `application/json` Content-Type?的主要内容,如果未能解决你的问题,请参考以下文章

Chrome中的慢速cors预检选项请求[关闭]

为啥经过身份验证的 CORS 请求的预检 OPTIONS 请求在 Chrome 中有效,但在 Firefox 中无效?

CORS 预检请求返回“403 Forbidden”;随后的请求,然后仅在 Chrome 中发送

如何重用 CORS 预检和资源请求之间的连接?

即使没有发出预检请求,也会在 POST 请求中出现 CORS 错误

CORS 选项预检悬挂