safari - Safari:重新加载后“由于访问控制检查而无法加载 Fetch API”
问题描述
我在 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 Instructure 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 错误,因为如果它是一个功能,Chrome 和 Firefox 可能会出现奇怪的行为。
要复制我对同一问题的变体:
- 在 Safari(带有文件缓存的 v13.2、桌面或 iOS)中,转到站点https://cidilabs.instructure.com/courses/3/pages/upload-slash-embed-image-test。我无法控制这个公共页面,如果它变成一个损坏的链接,我深表歉意。如果您有权访问 Canvas LMS,则可以通过 Canvas 图像上传工具将图像上传到模块页面来复制此页面。Canvas 将上传的图像作为重定向链接嵌入到 S3 存储桶。
- 然后刷新该页面,以在缓存图像上启动预检 CORS 请求,以查看损坏的图像链接。
解决方法选项:
- 使用带有嵌入式 CORS 重定向图像的页面时,请始终打开私人浏览器。该问题仅在缓存图像时发生。[对用户来说不是一个实用的解决方案]
- 向作为 CORS 重定向路径的所有可缓存资源添加终止的solidus(正斜杠)。仅当重定向路径看起来像文件而不是目录时才会出现此问题。[对于图像 src URL 的这种不好的风格,我感到很痛苦。但是,因为图像 src 确实是重定向而不是真正的文件,所以我认为将其显示为 dir 并不是完全糟糕的。] ** 最实用的坏解决方法
- 使图像 src URL 成为与其嵌入的页面不同的主机。仅当缓存的图像 src 重定向 URL与网页的主机相同时,才会出现此问题。【这太奇怪了!也许,Safari 以某种疯狂的方式缓存主机页面资源。]
- 转到带有 CORS 图像 src 重定向的页面时,请使用 FireFox 或 Chrome。该问题仅发生在 Safari 上。[糟糕的解决方法,切断了很多用户]
推荐阅读
- c# - Azure 事件网格订阅控制台应用程序
- r - 在R中合并具有不同变量的多个数据框
- javascript - 如何在javascript中验证上传的文件是有效的证书[证书内容]?
- html - echart是否可以在markline中为label设置高宽,或者在formatter中添加html标签和css属性?
- swift5 - MultiPeer Connectivity 没有快速连接 5
- javascript - 将函数引用到表的数据
- python - 如何将 TF-IDF 矢量化器输出作为输入提供给神经网络进行分类?
- android - 为什么我无法流式传输存储在 Dropbox 中的音频或视频?
- arm - armcc 到 armclang 移植错误:未知的寄存器名称 'cp15:0:c9:c12:0'
- histogram - 创建最小值为 0.01,最大值为 1 的千分尺直方图