ononline/onoffline 属性在上无效,仅 window 支持;应使用 addeventlistener 并配合 navigator.online 初始检测,online 后需健康检查而非直接重试。

不要在 上用 ononline 或 onoffline 属性——它们根本不会触发。 这两个事件只在 window 对象上原生支持, 不是合法目标,写上去等于没写。
为什么 ononline/onoffline 属性写法本身就不该用
这种写法(如 window.ononline = handler)已被标准弃用,且存在严重副作用:
- 它会覆盖其他模块注册的同名监听器,比如你引入的第三方 SDK 也设了
window.ononline,你的代码就会把它干掉 - 无法同时绑定多个回调,而实际项目中常需多处响应网络状态(UI、缓存、重试队列)
-
完全无效:浏览器不解析该属性,控制台无报错,但事件永不执行
window.addEventListener('online') 必须在页面早期注册
事件不会在页面加载时“补发”,首次状态已确定,必须靠 navigator.onLine 主动读取初始值:
- 在
DOMContentLoaded或React useEffect(() => {}, [])中立即执行if (navigator.onLine) { /* 渲染在线态 */ } - 紧接着调用
window.addEventListener('online', handler)和window.addEventListener('offline', handler) - 若用单页应用(SPA),路由离开或组件卸载时必须手动调用
removeEventListener,否则可能重复触发或内存泄漏
收到 online 事件后不能直接重发请求
操作系统报告“联网” ≠ 你的 API 可达。常见失败场景包括:
- WiFi 已连但光猫断网 →
navigator.onLine为true,但fetch('/api')立刻超时 - 代理配置错误或 DNS 污染 → 浏览器认为在线,实际所有请求都卡住
- 移动端锁屏后 WebSocket 断连,
online事件完全不触发,navigator.onLine仍为true
正确做法是:在 online 回调里发起一次轻量 fetch('/health', { method: 'HEAD', signal: AbortSignal.timeout(2000) }),仅当返回 2xx 才标记服务可用,再启动重试逻辑。
最易被忽略的是:DevTools 的离线模拟(Network 面板勾选 Offline)才是唯一可靠测试方式;拔网线在多网卡、虚拟机、企业网络下经常失效,navigator.onLine 根本不变。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











