Chrome中Service Worker的Online/Offline事件无法触发
问题分析与解决方案
你的Service Worker代码里的online/offline事件没触发,核心原因是:Chrome DevTools的“离线”复选框是模拟页面的离线状态,并不会直接触发Service Worker进程的online/offline事件——这两个事件仅在Service Worker自身的网络连接真实发生变化时才会触发,而非DevTools的模拟场景。
另外,Service Worker中的navigator.onLine属性可靠性有限,不能完全依赖它判断实时网络状态。
修复方案
方案1:通过页面传递在线状态给Service Worker
页面的online/offline事件是可靠的,可让页面主动将状态同步到Service Worker:
- 在页面脚本中添加状态同步代码:
// 页面端脚本 window.addEventListener('online', () => { if (navigator.serviceWorker.controller) { navigator.serviceWorker.controller.postMessage({ type: 'SYNC_ONLINE' }); } }); window.addEventListener('offline', () => { if (navigator.serviceWorker.controller) { navigator.serviceWorker.controller.postMessage({ type: 'SYNC_OFFLINE' }); } }); // 页面加载时同步初始状态 window.addEventListener('load', () => { if (navigator.serviceWorker.controller) { navigator.serviceWorker.controller.postMessage({ type: 'SYNC_STATUS', isOnline: navigator.onLine }); } });
- 修改Service Worker代码,监听页面发来的消息:
let isOnline = navigator.onLine; // 初始化状态 self.addEventListener('install', (event) => { console.log('SW: install'); console.log(`SW: install - ${isOnline ? 'online' : 'offline'}`); self.skipWaiting(); }); // 监听页面发来的状态同步消息 self.addEventListener('message', (event) => { switch(event.data.type) { case 'SYNC_ONLINE': isOnline = true; console.log('SW: Online (from page)'); break; case 'SYNC_OFFLINE': isOnline = false; console.log('SW: Offline (from page)'); break; case 'SYNC_STATUS': isOnline = event.data.isOnline; console.log(`SW: Sync initial status - ${isOnline ? 'online' : 'offline'}`); break; } }); self.addEventListener('fetch', function (event) { console.log('SW: flag', isOnline); console.log(`SW: Fetch ${isOnline ? 'Online' : 'Offline'}`); // 这里可以根据isOnline处理缓存/网络请求逻辑 });
方案2:在Fetch事件中直接判断网络状态
如果不需要提前监听状态,可在fetch事件中通过捕获网络错误来判断离线:
self.addEventListener('fetch', (event) => { event.respondWith( fetch(event.request) .then((response) => { console.log('SW: Fetch succeeded (online)'); return response; }) .catch((error) => { console.log('SW: Fetch failed (offline)'); // 这里返回缓存内容或离线页面 // return caches.match(event.request); }) ); });
额外注意点
- Service Worker的
skipWaiting()会让新的Service Worker立即激活,但要确保页面已完成注册,避免状态不同步。 - 测试离线状态时,除了DevTools的复选框,也可以断开真实网络(比如关闭WiFi)来验证Service Worker的
online/offline事件是否正常触发。
内容的提问来源于stack exchange,提问作者James Bender
相关产品推荐
相关产品推荐

