【问题标题】:Angular Service Worker ngsw-config.json S3/Cloudflare Image Caching CORS ErrorAngular Service Worker ngsw-config.json S3/Cloudflare 图像缓存 CORS 错误
【发布时间】:2020-12-28 10:58:50
【问题描述】:

在 Angular 9 应用程序中,当我将此图像缓存 sn-p 添加到 ngsw-config.json 时,出现 CORS 错误并且图像不显示。如果我删除这个 sn-p 应用程序可以正常工作(没有错误)。

访问“https://assets.myurl.net/images/banner.jpg”从 来源 'https://localhost:8100' 已被 CORS 策略阻止:否 请求中存在“Access-Control-Allow-Origin”标头 资源。如果不透明的响应满足您的需求,请设置请求的 模式为“no-cors”以获取禁用 CORS 的资源。

ngsw-config.json (sn-p):

"assetGroups": [{
    "name": "cdn",
    "installMode": "lazy",
    "updateMode": "lazy",
    "resources": {
        "urls": [
            "https://assets.myurl.net/**"
        ]
    }
}]

图像存储在具有 CORS 配置的 AWS S3 存储桶中:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
</CORSRule>
</CORSConfiguration>
  • Cloudflare 被用作 CDN(和 DNS)。
  • 该应用程序是最新的 9.x 版本:@angular 9.2.1、@angular/service-worker 9.1.12.
  • 向 img 和图片标签添加 crossorigin="anonymous" 似乎没有帮助。

在 Chrome/PC 中持续重现错误的步骤:

  1. 清除浏览器缓存
  2. 以私密/隐身方式打开浏览器
  3. 转到网站 -- 图片显示正常
  4. 点击刷新 - 图像不再显示 - 浏览器控制台中出现 CORS 错误

更新

根据这篇文章 (S3 not returning Access-Control-Allow-Origin headers?),问题似乎是服务工作者没有在请求标头中发送 Origin(因此 S3 不发送访问控制标头)。

Service Worker 请求(从 Chrome 控制台复制):

Request URL: https://assets.myurl.net/images/banner.jpg
Referrer Policy: strict-origin-when-cross-origin
Provisional headers are shown
Referer: https://localhost:8100/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36

首先,确保每个请求都有一个 Origin 标头。如果没有 Origin 标头 已发送,S3 不会发送访问控制标头,因为 S3 认为它们 不相关(通常情况下,它们是)。浏览器(CORS 机制的意思)将自动发送一个 Origin 标头时 通过 XMLHTTPRequest 进行跨域 HTTP 请求。

根据这篇文章 (S3 - Access-Control-Allow-Origin Header),S3 cors 脚本已更新为包括:

<AllowedMethod>HEAD</AllowedMethod>
<AllowedHeader>*</AllowedHeader>

向 img 标签添加 crossorigin="anonymous" 不会更改 service worker 请求标头。所以这并不能解决问题。

Cloudflare 缓存已被清除。

这个不起眼的帖子 (https://community.cloudflare.com/t/access-control-allow-origin-headers-stripped/158102/2) 包括:

如果您在源 Web 服务器上添加或更改 CORS 配置, 通过 URL 清除 Cloudflare 缓存不会更新 CORS 标头。

我通过添加随机查询字符串(即banner.jpg?q=abc)缓存了banner.jpg 图像。横幅图像始终正确显示(而其他图像仍显示 cors 错误)。 Chrome 控制台应用程序选项卡 > 缓存存储中的服务工作者缓存显示图像已缓存。 Cloudflare 缓存配置“缓存级别”= 标准“每次查询字符串更改时交付不同的资源”。

但是,如果我将新图像上传到 S3 banner01.jpg(即尚未被 Cloudflare 缓存),我确实会收到显示此图像的 cors 错误。 我通过上传不同的图像又尝试了 3 次图像名称,并没有得到一个 cors 错误。有趣的是,一个小时后,即使是新图像也显示 cors 错误。

curl 命令(未在标头中指定 Origin)在我的本地 PC 上成功运行。响应不包含 CORS 标头。例如

curl -v "https://assets.myurl.net/images/banner.jpg"

向 curl 命令添加源会返回 CORS 标头。例如

curl -v --header "Origin: https://www.example.com" "https://assets.myurl.net/images/banner.jpg"

access-control-allow-origin: https://www.example.com
access-control-allow-methods: GET, HEAD
access-control-allow-credentials: true

更新 2

我无法解释原因,但 Chrome 现在会在 Angular Service Worker 获取响应中返回 cors 标头。该请求不包含 Origin 标头。

accept-ranges: bytes
access-control-allow-methods: GET, HEAD
access-control-allow-origin: *

但是,Safari 没有。所有浏览器似乎都可以正常工作,但 Safari 仍然显示 cors 错误。

【问题讨论】:

  • 嗨,你确定你不需要为预检请求允许“OPTIONS”吗?
  • 这篇文章中的措辞有点含糊 (docs.aws.amazon.com/AmazonS3/latest/dev/cors.html) 但对于规则“*”它声明“该规则还允许预检 OPTIONS 请求中的所有标头” .所以我已将此 cors 规则添加到 S3 并更新了问题。
  • 有人说他们将允许的来源从“*”更改为“https://*”和“http://*”,试试看。
  • 顺便问一下,您确定您的 OPTIONS 标头没有被 cloudfront 缓存吗?
  • 同意 - 我认为 Cloudflare 正在缓存 cors 标头,并且正在使用旧 S3 cors 设置中的旧标头。我尝试过的任何操作似乎都无法清除此缓存(我只能重命名图像以解决该问题)。 support.cloudflare.com/hc/en-us/articles/…

标签: angular cors service-worker


【解决方案1】:

转到您的 S3 存储桶。单击权限,然后单击 CORS 配置。 如果您有 CORS 配置,请从此更改允许的来源:

<AllowedOrigin>*</AllowedOrigin>

<AllowedOrigin>http://*</AllowedOrigin>
<AllowedOrigin>https://*</AllowedOrigin>

如果您没有 CORS 配置,请添加如下配置:

<CORSConfiguration>
<CORSRule>
    <AllowedOrigin>http://*</AllowedOrigin>
    <AllowedOrigin>https://*</AllowedOrigin>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>DELETE</AllowedMethod>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
</CORSRule>
</CORSConfiguration>

【讨论】:

  • 这基本上是现在S3存储桶中存在的配置。但目前尚不清楚这里是否有专门修复 Safari 和 iOS 设备上的 CORS 错误的东西。根据上述问题中的注释,我可以在所有其他浏览器和设备上使用此功能。
  • 这个从 *example.com</AllowedOrigin> 的简单更改解决了我的 Safari 问题。我认为在 AllowedOrigin 上拥有您的完整网站 URL 也可以为您解决问题。
猜你喜欢
  • 2021-03-17
  • 2020-04-03
  • 2019-08-18
  • 2018-05-21
  • 1970-01-01
  • 2020-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多