我在 Safari 的 CORS 系统中遇到了一些奇怪的行为。 我有一个从 JS Fetch API 发送的 POST 请求,如下所示:
const res = await fetch('http://localhost:8888/myPath', {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
});
根据Safari的网络监控,请求头是这样的:
POST /myPath HTTP/1.1
Accept: */*
Content-Type: application/json
Origin: http://my.domain.com
Content-Length: 335
Accept-Language: en-gb
Host: localhost:8888
User-Agent: Mozilla/5.0...
Referer: http://my.domain.com
Accept-Encoding: gzip, deflate
Connection: keep-alive
并且以下响应来自服务器:
HTTP/1.1 200 OK
Date: Tue, 28 Jul 2020 19:15:45 GMT
Vary: Origin
Content-Length: 4
Content-Type: application/json
Access-Control-Allow-Origin: http://my.domain.com
Server: uvicorn
不幸的是,我的机器上没有 Wireshark,并且 Safari 不显示预检请求。所以我不知道是否会发生预检以及情况如何。
现在的问题是:当我有一个新的浏览器会话(例如,使用私有模式)并访问触发获取请求的文档时,一切正常。 仅在重新加载页面以再次发送 CORS 请求后,我在 Safari 控制台中收到“Fetch API 由于访问控制检查而无法加载”。 所以我推测,这与 Safari 如何缓存 CORS 请求/预检有关。
在 Firefox 和 Chrome 中,我的 CORS 请求非常有效。
我该如何解决这个问题?
我的建议是,如果您可以控制服务器,请在“http://localhost:8888/myPath/”上添加终止正斜杠。
const res = await fetch('http://localhost:8888/myPath/', {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
});
我提出这个建议的原因是我也有同样的问题。我对此问题的变体是,它表现为 Safari 无法对缓存图像进行预检 CORS 检查,其中图像 src 是重定向(Canvas Instruct URL 重定向到 AWS S3 存储桶)。根据您的示例,我怀疑这与您的 localhost 与 domain.com 主机名变化有关。
我的 Safari 控制台错误是主机页面的主机域被图像来源的域拒绝。我希望你的和这个类似。
FetchEvent.respondWith received an error:
TypeError: Cross-origin redirection to <actual image source>
denied by Cross-Origin Resource Sharing policy:
Origin <hosted page containing the image src redirect to image source>
is not allowed by Access-Control-Allow-Origin.
原来的 CORS 请求没问题。只是对“缓存资源”的预检检查失败了。我希望这是 Safari 的一个 bug,因为如果这是一个功能,Chrome 和 Firefox 可能会效仿这种奇怪的行为。 复制同一问题的变体:
也有同样的问题,这是我之前在 Safari iOS 中添加的 Firefox Focus 扩展(其中有一些内容拦截器)。
Settings > Safari > Extensions
并尝试禁用扩展程序。
通过将
localhost
127.0.0.1
解决了这个问题
就我而言,我使用的是
http
https
, 这使得 Safari 不包含我的
Authorization
标头。