NextJS12中PWA Service Worker报错:CacheStorage.has执行失败求解决方案
下面是针对Failed to execute 'has' on 'CacheStorage': Unexpected internal error报错的可行解决思路:
检查缓存名称合法性
CacheStorage对缓存名称有字符限制,避免使用包含空格、斜杠、冒号等特殊字符的名称,改用纯字母数字加版本号的命名方式,比如const CACHE_NAME = 'pwa-static-cache-v2'。限制缓存资源的大小与数量
浏览器CacheStorage有存储配额,过量缓存大资源(如高清图、视频)会触发内部错误。可在Service Worker的fetch事件中过滤大文件,只缓存静态资源:self.addEventListener('fetch', (event) => { event.respondWith( caches.match(event.request).then(cachedRes => { if (cachedRes) return cachedRes; return fetch(event.request).then(networkRes => { const contentLength = networkRes.headers.get('content-length'); // 仅缓存小于1MB的资源 if (contentLength && parseInt(contentLength) < 1024 * 1024) { caches.open(CACHE_NAME).then(cache => cache.put(event.request, networkRes.clone())); } return networkRes; }); }) ); });仅在生产环境测试Service Worker
NextJS12开发服务器的热重载机制会频繁触发Service Worker更新,容易导致CacheStorage异常。建议在next build && next start的生产环境下调试PWA功能,开发阶段暂时禁用Service Worker注册逻辑。手动清理浏览器缓存与Service Worker
浏览器缓存损坏可能引发该错误:打开开发者工具→Application面板,先清空CacheStorage下的所有缓存,再到Service Workers选项注销并删除当前Worker,最后刷新页面重新加载。调整Service Worker注册时机
确保在页面完全加载后再注册Service Worker,避免DOM未就绪时操作缓存。在_app.js中添加注册逻辑:import { useEffect } from 'react'; function MyApp({ Component, pageProps }) { useEffect(() => { if (typeof window !== 'undefined' && 'serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker.register('/sw.js') .catch(err => console.error('Service Worker注册失败:', err)); }); } }, []); return <Component {...pageProps} />; } export default MyApp;禁用HTTP/2服务器推送
若服务器开启了HTTP/2推送,可能与Service Worker的缓存逻辑冲突。可在NextJS配置文件中禁用相关设置,或调整服务器的HTTP/2推送规则。
内容的提问来源于stack exchange,提问作者Mostafa Tabatabaei

