You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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:

  1. 在页面脚本中添加状态同步代码:
// 页面端脚本
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
    });
  }
});
  1. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 07:03:15