使用Workbox配置Service Worker时离线触发'__jstcache'读取错误
问题
我使用Workbox模块处理Service Worker文件,代码如下:
importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'); const { routing, strategies, cacheableResponse, expiration, recipes } = workbox; const { registerRoute } = routing; const {offlineFallback} = recipes; const {ExpirationPlugin} = expiration; const { StaleWhileRevalidate } = strategies; const { CacheableResponsePlugin } = cacheableResponse; self.__WB_MANIFEST; registerRoute( ({ request }) => request.destination === 'script', // 仅匹配目标为script的请求 new StaleWhileRevalidate({ cacheName: 'js-cache', // 缓存名称 plugins: [ new CacheableResponsePlugin({ statuses: [0, 200] }), // 仅缓存状态码为0或200的响应 new ExpirationPlugin({ // 缓存有效期为一周 maxAgeSeconds: 7 * 24 * 60 * 60, }) ], }) ); workbox.routing.setCatchHandler(({ event }) => { if (event.request.destination === 'document') { return caches.match('/offline.html'); } return Response.error(); });
期望实现离线时提供缓存文件,但切换到离线模式后立即崩溃,抛出错误:Cannot read properties of null (reading '__jstcache'),错误截图显示该报错信息。
解决方案
这个错误核心原因是offline.html未被提前缓存,离线时caches.match('/offline.html')返回null,后续代码尝试访问null的属性导致崩溃。另外你的代码存在两个关键问题:一是self.__WB_MANIFEST仅被引用但未用于预缓存资源;二是导入了offlineFallback但未实际使用。
以下是修复后的代码:
importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'); const { routing, strategies, cacheableResponse, expiration, precaching, recipes } = workbox; const { registerRoute } = routing; const { offlineFallback } = recipes; const { ExpirationPlugin } = expiration; const { StaleWhileRevalidate } = strategies; const { CacheableResponsePlugin } = cacheableResponse; // 预缓存清单中的资源,需确保offline.html在构建生成的清单内 precaching.precacheAndRoute(self.__WB_MANIFEST); // 若构建工具未自动将offline.html加入清单,可手动添加 // precaching.precacheAndRoute([ // ...self.__WB_MANIFEST, // { url: '/offline.html', revision: '123' } // ]); // 缓存JS资源的路由规则 registerRoute( ({ request }) => request.destination === 'script', new StaleWhileRevalidate({ cacheName: 'js-cache', plugins: [ new CacheableResponsePlugin({ statuses: [0, 200] }), new ExpirationPlugin({ maxAgeSeconds: 7 * 24 * 60 * 60, }) ], }) ); // 使用Workbox内置的离线回退方案,自动处理页面离线访问 offlineFallback({ pageFallback: '/offline.html', });
关键改动说明
- 启用预缓存:调用
precaching.precacheAndRoute(self.__WB_MANIFEST),这会将构建工具生成的资源清单(包含offline.html)提前缓存,确保离线时能获取到。如果构建工具未自动包含offline.html,可以手动添加到预缓存列表。 - 使用
offlineFallbackrecipe:Workbox内置的该方案会自动处理离线回退逻辑,比手动编写setCatchHandler更可靠,它会确保指定的pageFallback文件被正确缓存。 - 可选:手动处理回退(不推荐):如果坚持手动写
setCatchHandler,需要添加await并判断缓存结果是否为null,避免直接访问null的属性:
workbox.routing.setCatchHandler(async ({ event }) => { if (event.request.destination === 'document') { const cachedPage = await caches.match('/offline.html'); return cachedPage || Response.error(); } return Response.error(); });
内容的提问来源于stack exchange,提问作者Danilo Kujacic
相关产品推荐
相关产品推荐

