英文:
Cache assets from a CMS for offline PWA?
问题
我正在为图片/视频编写一个Web媒体查看器,需要对这些媒体进行离线缓存。
我有一个清单和服务工作线程,所以它可以安装为PWA,我正在尝试缓存一组URL的媒体,代码如下:
let cache = await window.caches.open('pwa-assets');
for(let url of allAssetURLs) {
await cache.add(url);
}
这对于本地资源似乎可以正常工作,但如果这些URL来自不同域(例如CMS/CDN),我会遇到CORS错误。
来自源 'https://127.0.0.1:4173' 对 'https://storage.googleapis.com/....appspot.com/...example.mp4' 的访问已被CORS策略阻止:请求的资源上没有 'Access-Control-Allow-Origin' 头。如果不透明响应符合您的需求,请将请求的模式设置为 'no-cors',以禁用CORS获取资源。
Web.dev上有一个关于跨域缓存的注意事项1,但没有详细说明。
我正在尝试缓存的URL是存储在Google云存储中的文件,例如:
https://storage.googleapis.com/....appspot.com/...example.mp4
如果在<img/>
或<video/>
标签中使用这些URL,它们可以正常工作,所以我认为这不是CDN上的CORS标头问题。
英文:
I'm writing a web media viewer for images/videos and I need to cache that media for offline use.
I have a manifest and service worker so it can be installed as a PWA, and I'm trying to cache media from a list of URLs with esentially:
let cache = await window.caches.open('pwa-assets');
for(let url of allAssetURLs) {
await cache.add(url);
}
This seems to work fine for local assets, but if those URLs are on a different domain (from a CMS/CDN) I get this CORS error.
> Access to fetch at 'https://storage.googleapis.com/....appspot.com/...example.mp4' from origin 'https://127.0.0.1:4173' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Web.dev has a note that cross-domain caching is possible here, but doesn't say much about it.
The URLs I'm trying to cache are for files store in google cloud storage, for example:
> https://storage.googleapis.com/....appspot.com/...example.mp4
These do work if used in <img/>
or <video/>
tags, so I don't think it's a CORS header issue on the CDN.
答案1
得分: 0
你写道:
> 这些在 <img/>
或 <video/>
标签中使用时确实有效,因此我认为这不是 CDN 上的 CORS 标头问题。
在不同源之间加载这样的子资源默认与同源策略 (SOP) 兼容,不会触发 CORS 错误。请参阅相关部分MDN Web Docs 关于 SOP 的:
> 以下是一些可能嵌入跨源的资源的示例:[...]
>
> - 由 <img>
显示的图像。
> - 由 <video>
和 <audio>
播放的媒体。
你写道:
> 对于本地资源,这似乎运行良好,但如果这些 URL 在不同的域上(来自 CMS/CDN),我会得到 CORS 错误。
在 Cache
上调用 add
方法会导致 GET
请求。如果其参数位于不同的源上,则需要为相关资源配置 CORS,否则你将遇到 CORS 错误,正如你所经历的那样。请参阅 相关 MDN Web Docs 中的注意事项:
> 请注意,对于不透明的过滤响应 [...]
> 我们无法访问响应标头,因此此检查
> 将始终失败,字体将无法被缓存。 [...]
> 如果你尝试缓存来自不支持 CORS 的跨源域的其他资源,这是需要记住的事项!
你写道:
> 我尝试缓存的 URL 是存储在谷歌云存储中的文件,例如 https://storage.googleapis.com/....appspot.com/...example.mp4
。
谷歌存储文档的此页面解释了如何为你的存储桶配置 CORS,假设那些存储桶确实属于你。否则,你就没那么幸运了,不能在客户端缓存这些资源。
英文:
You write:
> These do work if used in <img/>
or <video/>
tags, so I don't think it's a CORS header issue on the CDN.
Loading such subresources across origins is by default compatible with the Same-Origin Policy (SOP) and doesn't trigger CORS errors. See the relevant section of the MDN Web Docs about the SOP:
> Here are some examples of resources which may be embedded cross-origin: [...]
>
> - Images displayed by <img>
.
> - Media played by <video>
and <audio>
.
You write:
> This seems to work fine for local assets, but if those URLs are on a different domain (from a CMS/CDN) I get this CORS error.
Invoking the add
method on a Cache
results in a GET
request. If its argument is on a different origin, the resource in question needs to be configured for CORS or you'll get a CORS error, as you've experienced. See the note in the relevant MDN Web Docs:
> Note that for opaque filtered responses [...]
> we can't access to [sic] the response headers, so this check
> will always fail and the font won't be cached. [...]
> It is something to keep in mind if you're attempting to
> cache other resources from a cross-origin domain that
> doesn't support CORS, though!
You write:
> The URLs I'm trying to cache are for files store in google cloud storage, for example https://storage.googleapis.com/....appspot.com/...example.mp4
.
This page of the Google Storage documentation explains how to configure CORS for your bucket(s), assuming those buckets are indeed yours. Otherwise, you're out of luck and won't be able to cache those resources on the client side.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论