Chrome最新版本中Service Worker Fetch事件未触发问题排查
Service Worker Fetch 事件未触发问题排查与修复
我之前也碰到过一模一样的情况:明明Service Worker注册成功,chrome://serviceworker-internals/也显示存在Fetch handler,但就是死活不触发Fetch事件。结合你提供的代码和状态信息,咱们一步步来排查修复:
1. 先修复Activate事件的语法错误
你的swa.js里的activate事件有个致命的语法问题:event.waitUntil只能接收单个Promise,但你把self.clients.claim()和缓存清理的Promise用逗号直接分开了,这会导致activate事件无法正确完成,Service Worker也就没法正常接管页面请求。
错误代码片段:
event.waitUntil(self.clients.claim(), caches.keys().then(function(cacheNames) { return Promise.all( cacheNames.map(function(cacheName) { if (cacheWhitelist.indexOf(cacheName) === -1) { return caches.delete(cacheName); } }) ); }) );
修复后的代码:
把两个操作的Promise用Promise.all包裹,作为event.waitUntil的单个参数:
self.addEventListener('activate', function(event) { debugger; var cacheWhitelist =['my-site-cache-v1','pages-cache-v1', 'blog-posts-cache-v1']; event.waitUntil( Promise.all([ // 主动接管所有处于scope下的已打开页面 self.clients.claim(), // 清理旧缓存 caches.keys().then(function(cacheNames) { return Promise.all( cacheNames.map(function(cacheName) { if (cacheWhitelist.indexOf(cacheName) === -1) { return caches.delete(cacheName); } }) ); }) ]) ); });
这里self.clients.claim()很关键,它能让激活后的Service Worker立即接管页面,不用等用户手动刷新。
2. 确认请求是否在Service Worker的Scope范围内
从你给出的状态信息看,Service Worker的Scope是https://me.development.symphoni.io:8443/resources/,这意味着只有这个路径下的资源请求才会触发Fetch事件:
- 确保你的页面本身就在
/resources/路径下(比如https://me.development.symphoni.io:8443/resources/index.html) - 如果需要拦截根路径的请求,注册时要手动指定Scope为
'/',同时还要在服务器配置Service-Worker-Allowed响应头,允许Service Worker使用更大的Scope范围。
3. 确保请求是在Service Worker激活后发起的
如果页面在Service Worker注册完成前就加载了资源(比如你缓存的jQuery),这些早期请求不会触发Fetch事件:
- 可以在注册成功的回调里监听状态,等Service Worker激活后刷新页面(仅调试用,生产环境谨慎使用):
navigator.serviceWorker.register('resources/swa.js').then(function(reg) { // 监听Service Worker更新状态 reg.addEventListener('updatefound', function() { const newWorker = reg.installing; newWorker.addEventListener('statechange', function() { if (newWorker.state === 'activated') { console.log('Service Worker已激活,刷新页面生效...'); window.location.reload(); } }); }); // 原有状态判断代码 if(reg.installing) { console.log('Service worker installing'); } else if(reg.waiting) { console.log('Service worker installed'); } else if(reg.active) { console.log('Service worker active'); } }).catch(function(error) { console.log('Registration failed with ' + error); });
4. 用Chrome DevTools辅助调试
- 打开DevTools的
Application标签,进入Service Workers面板,勾选Update on reload,这样每次刷新都会更新Service Worker,避免旧脚本缓存干扰。 - 可以点击
Unregister按钮清除所有旧的Service Worker,再重新加载页面,确保新脚本完全生效。
验证修复效果
按以下步骤操作:
- 在
chrome://serviceworker-internals/或DevTools里注销旧的Service Worker - 重新加载页面,看控制台是否打印
Opened cache(确认install事件触发) - 刷新页面或发起新的资源请求,检查控制台是否出现
Handling fetch event for ...(确认Fetch事件正常触发)
内容的提问来源于stack exchange,提问作者swarup
相关产品推荐
相关产品推荐

