应监听 online/offline 事件并结合主动 fetch 探测:页面加载时读取 navigator.onLine 初始值,绑定事件监听网络切换,再通过 HEAD 请求 /health 等 endpoint 验证服务可达性,避免仅依赖浏览器在线状态。
navigator.onLine 的实时变化navigator.onLine 是一个只读布尔值,但它**不会自动响应网络切换**——它只在页面加载时取一次初始值,之后除非手动触发或浏览器主动更新(如 Chrome/Firefox 在某些网络断开瞬间会同步更新),否则不会变。所以不能只靠轮询 navigator.onLine 来判断真实状态。
正确做法是监听全局的 online 和 offline 事件:
window.addEventListener('online', () => {
console.log('已联网');
});
window.addEventListener('offline', () => {
console.log('已离线');
});
offline 响应有延迟甚至不触发navigator.onLine 仍为 true
navigator.onLine,再绑定事件,避免错过初始状态online/offline 事件不够用这些事件无法检测以下真实业务场景:
503 Service Unavailable 或超时navigator.onLine 为 true,但实际无上行路由因此必须结合主动探测:
推荐用轻量 fetch 请求一个稳定、低开销的 endpoint(例如自己服务的 /health 或 https://www.google.com/generate_204):
async function checkServerReachable() {
try {
const res = await fetch('/health', { method: 'HEAD', cache: 'no-cache' });
return res.ok;
} catch (e) {
return false;
}
}
cache: 'no-cache' 防止 Service Worker 或浏览器缓存干扰判断检测到 offline 后,不能只弹个提示就结束。关键动作包括:

aria-busy="true" 或 CSS 类标明不可用状态offline 事件回调里直接调 alert() —— 移动端可能被拦截,且打断用户操作流UI 提示建议用轻量 toast,带明确恢复机制(如“重试”按钮),而不是全屏遮罩。
Android WebView 和 iOS WKWebView 对 online/offline 事件支持不一致:
fetch 探测self.registration.update() + waiting 状态间接感知网络恢复(需配合 message channel)navigator.onLine 在 Electron 中反映的是主进程网络状态,渲染进程需通过 IPC 同步真正健壮的网络状态管理,永远是「事件监听 + 主动探测 + 业务层兜底」三层组合。别指望单个 API 解决所有问题。