Service Worker注册成功但无法拦截请求,是什么原因?

Des.振岚 阅读 67

我在给PWA应用添加Service Worker时遇到了奇怪的问题。按照教程写好了fetch事件监听,控制台也显示注册成功,但刷新页面时网络面板显示所有请求都是直接走的网络,没有触发缓存逻辑。已经检查过scope路径和浏览器设置,也没看到报错,这是为什么呢?

代码大致是这样的:

self.addEventListener('install', (e) => {
  e.waitUntil(
    caches.open('v1').then(cache => cache.addAll(['/index.html', '/styles.css']))
  )
});

self.addEventListener('fetch', (e) => {
  console.log('拦截到请求!'); // 这行从未执行
  e.respondWith(caches.match(e.request).catch(() => fetch(e.request)));
});

之前试过把事件写在activate里,但没用。难道是事件监听顺序有问题吗?

我来解答 赞 9 收藏
二维码
手机扫码查看
2 条解答
萌新.梓轩
应该是你的 Service Worker 没有正确接管页面请求。确保注册时 scope 覆盖了页面路径,并且页面在 HTTPS 或 localhost 下运行。

检查注册代码是否像这样:

if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js', { scope: '/' })
.then(reg => console.log('SW registered:', reg.scope));
}


同时把 fetch 监听写在 sw.js 的顶层,不是 install 或 activate 里,你现在的写法是对的,但要确保 sw.js 被正确加载执行。刷新两次页面,第一次注册,第二次才会拦截请求。
点赞 1
2026-02-12 12:06
Mc.燕丽
Mc.燕丽 Lv1
嗯,这个问题我以前也踩过坑,确实挺让人抓狂的。先说结论吧:你现在的Service Worker虽然注册成功了,但可能没有控制页面(active状态),或者scope范围不对,导致fetch事件根本没触发。

别走弯路,直接告诉你怎么解决:

1. 确保你的Service Worker已经激活并且控制了页面。可以加个activate事件监听,在里面打印一下:
self.addEventListener('activate', (e) => {
console.log('SW已激活');
});

如果这个都没触发,说明scope有问题或者页面没被控制。

2. 检查scope路径是否正确。即使注册成功,如果scope范围不包含当前页面路径,Service Worker也不会拦截请求。比如你在/app/路径下注册,但scope设成了/,可能会出问题。建议明确设置scope为相对路径:
navigator.serviceWorker.register('/app/sw.js', { scope: '/app/' });


3. 强制让SW控制页面。有时候SW注册成功了但没控制页面,可以手动加上:
if (!navigator.serviceWorker.controller) {
navigator.serviceWorker.ready.then(() => {
location.reload();
});
}


4. 刷新缓存。浏览器可能会缓存旧的SW文件,导致逻辑不对。开发时可以在install事件里清理旧缓存:
caches.keys().then(keys => Promise.all(keys.map(key => caches.delete(key))));


最后再提醒一下,确保你的fetch事件监听器在正确的生命周期里执行,别放在install里面。按照这些步骤调整,基本就能解决问题了。要是还是不行,检查下网络面板里SW的状态是不是正常激活了。
点赞 6
2026-02-02 10:01