如何为离线PWA缓存来自CMS/CDN的跨域媒体资源?
解决PWA缓存跨域媒体资源的CORS问题
问题原因
你用cache.add()缓存跨域资源时触发CORS错误,核心差异在于:
cache.add()内部调用的fetch API默认使用cors模式,要求目标服务器返回Access-Control-Allow-Origin头,否则浏览器会拦截请求。- 而
<img>/<video>标签加载媒体资源时,默认采用no-cors模式,浏览器不会校验CORS头,所以能正常播放,但这种模式下获取的是「不透明响应」。
解决方案
改用cache.put()配合fetch的no-cors模式,直接获取不透明响应并缓存,代码如下:
let cache = await window.caches.open('pwa-assets'); for(let url of allAssetURLs) { // 以no-cors模式请求资源,跳过CORS校验 const response = await fetch(url, { mode: 'no-cors' }); // 将不透明响应存入缓存 await cache.put(url, response); }
关键说明
- 不透明响应的状态码为0,无法读取响应内容(比如
response.text()或response.blob()会失败),但完全可以在<img>/<video>标签中正常使用,刚好满足离线播放需求。 - 不透明响应会占用浏览器缓存配额,注意控制缓存的资源数量和大小,避免触发浏览器自动清理机制。
- 如果后续需要对缓存资源做内容处理(比如提取帧、转码),则必须配置谷歌云存储的CORS规则,允许你的站点Origin访问;仅做离线播放的话,上述方案足够。
内容的提问来源于stack exchange,提问作者nicholas
相关产品推荐
相关产品推荐

