无法在标头中没有 no-cors 的情况下获取 POST

Posted

技术标签:

【中文标题】无法在标头中没有 no-cors 的情况下获取 POST【英文标题】:Unable to fetch POST without no-cors in header 【发布时间】:2016-10-06 16:50:46 【问题描述】:

提出这样的要求:

return fetch(
            'http://localhost:8000/login',
               method: 'POST',
                headers: new Headers(
                   "Content-Type": "application/json",
                    "Accept":"application/json"
                ),

                body: JSON.stringify(
                   'name': 'Tom', 'password': 'Soyer'
                )
             
           ).then( response =>  console.log(response);)
            .catch(err => console.log(err))

使用方法 OPTIONS 代替 POST 运行请求。 仅在添加模式下:'no-cors' 请求变为 POST:

return fetch(
            'http://localhost:8000/login',
               method: 'POST',
                mode: 'no-cors',
                headers: new Headers(
                   "Content-Type": "application/json",
                    "Accept":"application/json"
                ),
                body: JSON.stringify(
                   'name': 'Tom', 'password': 'Soyer'
                )
             
           ).then( response =>  console.log(response);)
            .catch(err => console.log(err))

但响应不正常(即使网络响应状态为 200):type: "opaque", url: "", status: 0, ok: false, statusText: ""... 我想是因为

Content-Type 标头的唯一允许值是: application/x-www-form-urlencoded multipart/form-data text/plain

这里描述https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

有什么方法可以通过 fetch 实现 POST json 数据吗?

【问题讨论】:

好吧,只是 a) 不要发出跨域 http 请求或 b) 用适当的 CORS 标头回答它们 你的问题解决了吗..如果是,你能更新你的答案吗.. 【参考方案1】:

您发送的自定义 Content-Type 标头会导致您的请求被预检,这意味着包含有关即将发送的 POST 请求的一些元数据的 OPTIONS 请求将在之前发送 实际的 POST 请求。

您的服务器需要准备好处理此 OPTIONS 请求。您尚未指定服务器写入的内容,但例如使用 express,您可以注册一个中间件,拦截所有 'OPTIONS' 请求,设置 Access-Control-Allow-Origin: *Access-Control-Allow-Headers: Content-Type 标头,并以 200 响应。

如果您可以使用 'Content-Type': 'text/plain' 标头发出请求,那将解决您的问题。或者,您可以使用完全绕过 XHR 的东西,例如 JSONP。

【讨论】:

【参考方案2】:

当使用non-cors 时,所有标题都必须是有效的simple-headerscontent-type 标头的唯一有效值是 simple-header 是:

headers: [
  ['Content-Type', 'application/x-www-form-urlencoded'],
  ['Content-Type', 'multipart/form-data'],
  ['Content-Type', 'text/plain'],
]

有意外情况的例外情况:

headers: [
  ['Content-Type', 'application/csp-report'],
  ['Content-Type', 'application/expect-ct-report+json'],
  ['Content-Type', 'application/xss-auditor-report'],
  ['Content-Type', 'application/ocsp-request'],
]
simple-header cors-protocol-exceptions

【讨论】:

唯一有效的值 [...] 不完全正确。例如,application/x-www-form-urlencoded; whatever 是允许的。 ['Content-Type', 'application/x-www-form-urlencoded'] 在我的答案中列为 simple-header 再次阅读我的评论。我的意思是,您可以在分号后添加任何内容。【参考方案3】:

如果您尝试调用 api 并在您的 react 应用程序中遇到此问题,您可以向服务器添加代理,然后 cors 错误将被删除

只需在 package.json 中添加这一行

"proxy":"url-to-your-server",

【讨论】:

以上是关于无法在标头中没有 no-cors 的情况下获取 POST的主要内容,如果未能解决你的问题,请参考以下文章

对 Flask 后端响应正文的获取请求为 null 且没有 cors 并且在没有 no-cors 的情况下失败

将 no-cors 包含在标头中以获取 react.js 中的 json 内容时出现奇怪的错误

当使用 mode: no-cors 请求时,浏览器没有添加我在前端代码中设置的请求标头

如何在没有任何 vue 库的情况下在 vue 回调中获取 http 响应标头(axios)

解决 API 开发中遇到的 CORS 问题

如何在 fetch() 中使用 no-cors