React使用Service Worker实现离线页面,支持localhost运行仅缓存根路由
解决方案
1. 适配localhost环境生效
你当前的代码默认限制了仅生产环境注册Service Worker,按以下步骤修改即可让localhost环境也正常运行:
- 修改
register函数的触发条件,移除仅生产环境的限制:
将原代码中的判断逻辑
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator)
调整为:
if ('serviceWorker' in navigator)
如果需要保留生产环境才正式启用的逻辑,也可以改为仅额外放开localhost的权限:
if ((process.env.NODE_ENV === 'production' || isLocalhost) && 'serviceWorker' in navigator)
- 原有的
checkValidServiceWorker逻辑不需要调整,已经可以正常检测localhost环境下的Service Worker文件是否存在,不会影响离线功能运行。
2. 仅缓存根路由/
你当前贴出的是Service Worker的注册代码,缓存逻辑需要在你的service-worker.js核心文件中修改,按以下两种场景适配即可:
- 如果你用的是Create React App默认的Workbox方案:
// 仅匹配根路由的GET请求做缓存 workbox.routing.registerRoute( ({ url }) => url.pathname === '/', new workbox.strategies.StaleWhileRevalidate({ cacheName: 'root-page-cache' }) ) // 其余所有请求都直接走网络,不做缓存 workbox.routing.setDefaultHandler(new workbox.strategies.NetworkOnly())
- 如果你是手写原生Service Worker逻辑:
self.addEventListener('fetch', (event) => { const requestUrl = new URL(event.request.url) // 仅处理根路由的GET请求 if (event.request.method === 'GET' && requestUrl.pathname === '/') { event.respondWith( caches.match(event.request) .then(cachedRes => { // 有缓存优先返回缓存,同时后台更新缓存内容 const fetchPromise = fetch(event.request).then(networkRes => { caches.open('root-page-cache').then(cache => { cache.put(event.request, networkRes.clone()) }) return networkRes }) return cachedRes || fetchPromise }) ) return } // 其他所有请求直接走网络,不做缓存处理 event.respondWith(fetch(event.request)) })
注意:修改完成后需要清除浏览器之前注册的旧Service Worker,刷新页面后新的规则才会生效,避免旧缓存干扰测试。
内容的提问来源于stack exchange,提问作者Ajit Kumar
相关产品推荐
相关产品推荐

