PWA离线缓存怎么不生效?明明注册了service worker啊

东方玉鑫 阅读 55

我按照教程写了 service worker,也成功注册了,在 DevTools 的 Application 面板里能看到它处于 active 状态。但一断网页面就打不开,提示“无法访问此网站”。是不是缓存策略写错了?

我尝试在 install 事件里用 caches.open()addAll() 缓存首页和关键资源,但好像根本没存进去。控制台也没报错,就是离线时完全不能用。

self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open('v1').then((cache) => {
      return cache.addAll([
        '/',
        '/index.html',
        '/styles/main.css',
        '/scripts/app.js'
      ]);
    })
  );
});
我来解答 赞 6 收藏
二维码
手机扫码查看
1 条解答
可欣
可欣 Lv1
这个问题很典型,十有八九是你少写了一个关键的东西:fetch 事件监听器。

你只写了 install 事件来缓存资源,但这只是把东西存到缓存区里。Service Worker 还需要拦截页面发出的网络请求,从缓存里把东西返回给页面。这两个是缺一不可的。

来,加上 fetch 事件的处理:

// 拦截网络请求
self.addEventListener('fetch', (event) => {
event.respondWith(
// 先去缓存里找
caches.match(event.request).then((response) => {
// 如果缓存里有,直接返回
if (response) {
return response;
}
// 缓存里没有,去网络请求
return fetch(event.request);
})
);
});


把这段代码加到你的 service worker 文件里,然后重新注册一下。更新 service worker 有个小技巧,建议在注册时加上这样一段:

if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js').then((registration) => {
console.log('SW 注册成功:', registration);
}).catch((error) => {
console.log('SW 注册失败:', error);
});
}


注册成功后,去 Application 面板里刷新一下,然后勾选 Offline 选项,再刷新页面试试能不能打开。

另外还有几个可能踩坑的地方:

缓存的路径要对得上。如果你的页面是通过 / 访问的,那就缓存 /,如果是通过 /index.html 访问的,那就两个都缓存上,别漏了。

更新缓存要换名字。你现在的缓存名叫 v1,下次想更新缓存内容的时候,得改成 v2 或者别的名字,不然浏览器会一直用旧缓存。懒人才不想改名字的话,可以写个自动清理旧缓存的逻辑。

调试的时候用 DevTools。Application 面板里能看到 Cache Storage,看看里面有没有你缓存的文件。如果缓存是空的,说明 addAll 可能失败了,可能是路径写错了或者服务器没返回正确的响应。

你先加上 fetch 事件监听器试试,大概率就能工作了。
点赞
2026-03-14 15:03