[英]Angular Service Worker ngsw-config.json S3/Cloudflare Image Caching CORS Error
In an Angular 9 app, when I add this image caching snippet to ngsw-config.json, I get a CORS error and images don't display.在 Angular 9 应用程序中,当我将此图像缓存片段添加到 ngsw-config.json 时,出现 CORS 错误并且图像不显示。 If I remove this snippet the app works correctly (with no errors).如果我删除此代码段,应用程序将正常工作(没有错误)。
Access to fetch at 'https://assets.myurl.net/images/banner.jpg' from origin 'https://localhost:8100' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.从源“https://localhost:8100”获取“https://assets.myurl.net/images/banner.jpg”的访问已被 CORS 策略阻止:没有“Access-Control-Allow-Origin”标头存在于请求的资源上。 If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.如果不透明响应满足您的需求,请将请求的模式设置为“no-cors”以在禁用 CORS 的情况下获取资源。
ngsw-config.json (snippet): ngsw-config.json(片段):
"assetGroups": [{
"name": "cdn",
"installMode": "lazy",
"updateMode": "lazy",
"resources": {
"urls": [
"https://assets.myurl.net/**"
]
}
}]
Images are stored in an AWS S3 bucket with CORS configuration:图像存储在具有 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>
Steps to consistently reproduce the error in Chrome/PC:在 Chrome/PC 中始终重现错误的步骤:
UPDATE更新
Based on this post ( S3 not returning Access-Control-Allow-Origin headers? ) the issue appears to be that the service worker does not send an Origin in the request header (so S3 doesn't send access-control headers).基于这篇文章( S3 不返回 Access-Control-Allow-Origin 标头? ),问题似乎是 service worker 没有在请求标头中发送 Origin(因此 S3 不发送访问控制标头)。
Service Worker Request (copied from Chrome console): 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
First of all, make sure an Origin header with every request.首先,确保每个请求都有一个 Origin 标头。 If no Origin header is sent, S3 won't send access-control headers, as S3 deems them irrelevant (and typically, they are).如果没有发送 Origin 标头,S3 将不会发送访问控制标头,因为 S3 认为它们不相关(通常情况下,它们是相关的)。 A browser (for which the CORS mechanism is meant) will automatically send an Origin header when doing cross-origin HTTP requests through XMLHTTPRequest.当通过 XMLHTTPRequest 执行跨域 HTTP 请求时,浏览器(CORS 机制针对的)将自动发送一个 Origin 标头。
Based on this post ( S3 - Access-Control-Allow-Origin Header ) the S3 cors script has been updated to include:基于这篇文章( S3 - Access-Control-Allow-Origin Header ),S3 cors 脚本已更新为包括:
<AllowedMethod>HEAD</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
Adding crossorigin="anonymous" to img tags doesn't change the service worker request header.将 crossorigin="anonymous" 添加到 img 标签不会更改服务工作者请求标头。 So this doesn't fix the problem.所以这并不能解决问题。
Cloudflare cache has been purged. Cloudflare 缓存已被清除。
This obscure post ( https://community.cloudflare.com/t/access-control-allow-origin-headers-stripped/158102/2 ) includes:这篇晦涩的帖子 ( https://community.cloudflare.com/t/access-control-allow-origin-headers-stripped/158102/2 ) 包括:
If you add or change CORS configuration at your origin web server, purging the Cloudflare cache by URL does NOT update the CORS headers.如果您在源站 Web 服务器上添加或更改 CORS 配置,按 URL 清除 Cloudflare 缓存不会更新 CORS 标头。
I cache busted the banner.jpg image by adding a random querystring (ie banner.jpg?q=abc).我通过添加随机查询字符串(即banner.jpg?q=abc)缓存破坏了banner.jpg 图像。 The banner image always displays correctly (while the other images still show cors errors).横幅图像始终正确显示(而其他图像仍然显示 cors 错误)。 The service worker cache in Chrome console Application Tab > Cache Storage shows that the image as cached. Chrome 控制台应用程序选项卡 > 缓存存储中的服务工作者缓存显示图像已缓存。 Cloudflare caching configuration "Caching Level" = Standard "delivers a different resource each time the query string changes". Cloudflare 缓存配置“缓存级别”=标准“每次查询字符串更改时都会提供不同的资源”。
However, if I upload a new image to S3 banner01.jpg (ie not already cached by Cloudflare) I do get a cors error showing this image.但是,如果我将新图像上传到 S3 banner01.jpg(即尚未被 Cloudflare 缓存),我确实会收到显示此图像的 cors 错误。 I tried this three additional times by uploading different image names and did not get a cors error.我通过上传不同的图像名称又尝试了三次,但没有出现 cors 错误。 Interestingly, an hour later even the new images are showing cors errors.有趣的是,一个小时后,即使是新图像也显示 cors 错误。
A curl command (that does not specify Origin in header) runs successfully on my local PC. curl 命令(未在标头中指定 Origin)在我的本地 PC 上成功运行。 The response does not contain CORS headers.响应不包含 CORS 标头。 eg例如
curl -v "https://assets.myurl.net/images/banner.jpg"
Adding origin to the curl command does return CORS headers.将 origin 添加到 curl 命令确实会返回 CORS 标头。 eg例如
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
UPDATE 2更新 2
I can't explain why, but Chrome now returns cors headers in the Angular Service Worker fetch response.我无法解释为什么,但 Chrome 现在在 Angular Service Worker fetch 响应中返回 cors 标头。 The request does NOT include an Origin header.该请求不包含 Origin 标头。
accept-ranges: bytes
access-control-allow-methods: GET, HEAD
access-control-allow-origin: *
However, Safari does not.但是,Safari 没有。 All browsers appear to be working okay but Safari still shows cors errors.所有浏览器似乎都可以正常工作,但 Safari 仍然显示 cors 错误。
Go to your S3 bucket.转到您的 S3 存储桶。 Click on Permissions, then CORS configuration.单击权限,然后单击 CORS 配置。 If you have a CORS configuration, change the allowed origin from this:如果您有 CORS 配置,请更改允许的来源:
<AllowedOrigin>*</AllowedOrigin>
TO到
<AllowedOrigin>http://*</AllowedOrigin>
<AllowedOrigin>https://*</AllowedOrigin>
If you don't have a CORS configuration, add a config like this:如果您没有 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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.