Safari:重新加载后“由于访问控制检查,Fetch API 无法加载”

问题描述 投票:0回答:5

我在 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 请求非常有效。

我该如何解决这个问题?

safari cors fetch
5个回答
6
投票

我的建议是,如果您可以控制服务器,请在“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(v13.2,打开文件缓存,桌面或 iOS)中,转到站点
    https://cidilabs.instruct.com/courses/3/pages/upload-slash-embed-image-test
  1. 。我不控制这个公共页面,如果它成为一个损坏的链接,我深表歉意。如果您有权访问 Canvas LMS,则可以通过 Canvas 图像上传工具将图像上传到模块页面来复制此页面。 Canvas 将上传的图像作为重定向链接嵌入到 S3 存储桶。 然后刷新该页面,对缓存的图像发起预检 CORS 请求,以查看损坏的图像链接。
  2. 解决方法选项:

使用嵌入 CORS 重定向图像的页面时,请始终打开专用浏览器。仅当图像被缓存时才会出现此问题。 [对于用户来说不是一个实用的解决方案]
  • 向作为 CORS 重定向路径的所有可缓存资源添加终止斜线(正斜杠)。仅当重定向路径看起来像文件而不是目录时,才会出现此问题。 [对于图像 src URL 来说这种风格很糟糕,我感到很困惑。但是,因为图像 src 实际上是一个重定向,而不是一个真正的文件,所以我认为将其显示为目录并不完全是坏事。] ** 最实用的坏解决方法
  • 将图像 src URL 设为与其嵌入的页面不同的主机。只有当缓存的图像 src 重定向 URL 与网页的主机相同时,才会出现此问题。 【这太奇怪了!也许,Safari 会以某种疯狂的方式缓存主机页面资源。]
  • 转到具有 CORS 图像 src 重定向的页面时,请使用 FireFox 或 Chrome。该问题仅发生在 Safari 上。 [糟糕的解决方法,削减了很多用户]
  • 对我来说,是广告拦截器打破了这一点。我有一个名为“advertiser_id”的查询参数,我的 Adblocker 将其识别为“需要阻止”。导致问题描述的 cors 错误。

0
投票

也有同样的问题,这是我之前在 Safari iOS 中添加的 Firefox Focus 扩展(其中有一些内容拦截器)。


0
投票
Settings > Safari > Extensions

并尝试禁用扩展程序。

通过将 

localhost

0
投票
127.0.0.1

解决了这个问题

    
就我而言,我使用的是 

http

-1
投票
https

, 这使得 Safari 不包含我的

Authorization
标头。
    

© www.soinside.com 2019 - 2024. All rights reserved.