cors 与 fetch 以及何时发出选项请求时非常困惑
Posted
技术标签:
【中文标题】cors 与 fetch 以及何时发出选项请求时非常困惑【英文标题】:Very confused by cors with fetch and when an options request is made 【发布时间】:2017-03-16 08:47:41 【问题描述】:我有以下使用whatwg fetch的代码:
const headers = new Headers();
//uncommenting this causes the preflight options request to be sent
//headers.append('x-something', 'foo');
const response = await fetch('http://localhost:5000/api/managers',
headers,
credentials: 'include'
);
除非我取消注释此行,否则上述代码不会发出预检选项请求:
//headers.append('x-something', 'foo');
我将服务器配置为允许 localhost 请求:
app.use(cors(
origin: 'http://localhost:4040'
));
如果我使用 credentials: 'include'
选项发出请求,我会在 chrome 浏览器中收到以下错误:
Fetch API 无法加载 http://localhost:5000/api/managers。证书 flag 为“true”,但“Access-Control-Allow-Credentials”标头为 ''。必须为“true”才能允许凭据。起源 'http://localhost:4040' 因此不允许访问。
如果我删除 credentials: 'include'
但有这样的自定义标题:
headers.append('x-something', 'foo');
const response = await fetch('http://localhost:5000/api/managers',
headers
);
然后,chrome 网络选项卡仅显示带有 204 No Content
响应的 OPTIONS 请求,即使服务器返回了 JSON 响应。
我不明白为什么 chrome 网络选项卡没有显示带有 JSON 响应的 GET 请求。
请求和响应如下所示,带有 204 无内容响应:
Request URL:http://localhost:5000/api/managers
Request Method:OPTIONS
Status Code:204 No Content
Remote Address:[::1]:5000
Response Headers
view source
Access-Control-Allow-Headers:x-something
Access-Control-Allow-Methods:GET,HEAD,PUT,POST,DELETE,PATCH
Access-Control-Allow-Origin:http://localhost:4040
Connection:keep-alive
Date:Wed, 02 Nov 2016 21:23:24 GMT
Vary:Accept-Encoding
Request Headers
view source
Accept:*/*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:x-something
Access-Control-Request-Method:GET
Cache-Control:no-cache
Connection:keep-alive
Host:localhost:5000
Origin:http://localhost:4040
Pragma:no-cache
Referer:http://localhost:4040/base/winratio
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/54.0.2840.71 Safari/537.36
Name
managers
/api
info?t=1478121804370
/sockjs-node
如果我把代码写成这样:
const response = await fetch('http://localhost:5000/api/managers',
);
然后谷歌浏览器网络选项卡只显示一个带有 200 HTTP 响应的 GET 请求和它返回的 json:
Request URL:http://localhost:5000/api/managers
Request Method:GET
Status Code:200 OK
Remote Address:[::1]:5000
Response Headers
view source
Access-Control-Allow-Origin:http://localhost:4040
Connection:keep-alive
Content-Length:1104
Content-Type:application/json; charset=utf-8
Date:Wed, 02 Nov 2016 21:35:21 GMT
Vary:Accept-Encoding
X-Content-Type-Options:nosniff
X-DNS-Prefetch-Control:off
X-Download-Options:noopen
X-Frame-Options:SAMEORIGIN
X-XSS-Protection:1; mode=block
Request Headers
view source
Accept:*/*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Host:localhost:5000
Origin:http://localhost:4040
Pragma:no-cache
Referer:http://localhost:4040/base/winratio
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
Name
【问题讨论】:
developer.mozilla.org/en-US/docs/Web/HTTP/… 【参考方案1】:“有些请求不会触发 CORS 预检。在本文中这些请求称为“简单请求”,尽管 Fetch 规范(定义 CORS)没有使用该术语。”
继续阅读https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Simple_requests
【讨论】:
【参考方案2】:如错误消息所示,您的服务器需要将Access-Control-Allow-Credentials: true
作为响应标头。这在 Fetch 中也有解释:https://fetch.spec.whatwg.org/#cors-protocol-and-credentials
【讨论】:
以上是关于cors 与 fetch 以及何时发出选项请求时非常困惑的主要内容,如果未能解决你的问题,请参考以下文章
如何在 fetch 中执行跨域请求以及异步等待? (CORS 错误)[重复]
发出 POST 请求时出现 Google Cloud Function CORS 错误
本地 Javascript Fetch Post 请求失败,调用 ASP.NET Core 2.2 Web API。 CORS 已启用