使用Workbox缓存无CORS支持的CDN资源遇CORS错误,求解决方案
解决Workbox预缓存CDN资源的CORS问题
你已经找对了核心方向,但可能忽略了预缓存阶段的请求并没有应用你设置的自定义fetch插件——当前配置只处理了运行时通过路由匹配的请求,而InjectManifest生成的预缓存列表里的资源请求,依然会用Workbox默认的CORS模式发起,这才是报错的根源。
下面分两步帮你修正配置:
1. 修改预缓存请求的模式
在workbox-webpack-plugin的InjectManifest配置中,添加manifestTransforms来修改预缓存条目的请求选项,让预缓存的CDN资源请求强制使用no-cors模式:
// webpack配置中的InjectManifest部分 new InjectManifest({ // 你的已有配置(比如swSrc、modifyURLPrefix等) modifyURLPrefix: { 'js/': 'https://example.com/js/' // 你的CDN前缀配置 }, manifestTransforms: [ (manifestEntries) => { const modifiedEntries = manifestEntries.map(entry => { // 仅针对CDN域名的资源修改请求模式 if (entry.url.startsWith('https://example.com/')) { return { ...entry, requestOptions: { mode: 'no-cors' } }; } return entry; }); return { manifest: modifiedEntries, warnings: [] }; } ] })
2. 优化运行时路由配置
你当前的运行时路由逻辑基本正确,但可以补充细节避免冗余处理:
- 只对非
no-cors模式的请求做修改,避免重复处理; - 确保
cacheableResponse插件明确包含状态码0(因为no-cors返回的是opaque响应,状态码固定为0)。
调整后的代码如下:
const customFetchPlugin = { requestWillFetch: ({ request }) => { // 仅当请求模式不是no-cors时,才修改模式 if (request.mode !== 'no-cors') { return new Request(request, { mode: 'no-cors' }); } return request; } }; workbox.routing.registerRoute( /https:\/\/example\.com\/.*\.(js|css)/, new workbox.strategies.StaleWhileRevalidate({ cacheName: '3rd-cache', plugins: [ new workbox.cacheableResponse.Plugin({ statuses: [0, 200] }), customFetchPlugin ] }) );
关键注意事项
使用no-cors模式获取的是opaque响应,你无法读取响应内容、状态码等细节,但只要你只是需要缓存并将这些资源返回给页面使用,这完全不影响——浏览器会正常加载缓存的opaque资源。
内容的提问来源于stack exchange,提问作者Sumit
相关产品推荐
相关产品推荐

