navigator.onLine 不可靠,仅反映本地网络接口状态而非真实联网能力;需结合 online/offline 事件监听与轻量探测请求(如 fetch /health)验证业务可达性。

navigator.onLine 不是“是否能访问互联网”的可靠判断依据,它只反映浏览器是否认为自己连着网络设备(比如网线插着、Wi-Fi 显示已连接),哪怕路由器断网、DNS 失败、防火墙拦截、目标服务器宕机,它都可能返回 true。
为什么 navigator.onLine 返回值不准
这个属性底层不发任何请求,只是读取操作系统或浏览器内核对“网络接口状态”的缓存快照。Chrome 启动时若未联网,有时仍返回 true;Safari 在某些 macOS 睡眠唤醒后会卡在旧状态;iOS Safari 甚至在飞行模式下偶尔延迟更新。
- 它无法区分“局域网通”和“能上公网”
- 它不检查 DNS 是否可用、TCP 连接是否能建、HTTPS 是否能握手
- 初始值不可信,首次应以
online/offline事件触发后的值为准
online/offline 事件监听必须绑定到 window
这两个事件只在 window 对象上触发,绑到 document、body 或任意 DOM 元素都收不到。而且事件是冒泡的,但不会捕获——所以别用第三个参数 true。
- 务必在组件挂载时添加,卸载时调用
removeEventListener,否则可能触发已销毁实例的方法 - 事件触发是异步的,但延迟极低;不过仍建议在回调里立刻读取
navigator.onLine,而非依赖传参 - 部分老旧 Android WebView 不支持这两个事件,需降级为轮询 + 小图请求兜底
真正要判断“能否访问业务接口”,得自己发请求
靠 navigator.onLine 做核心逻辑分支(比如跳过登录、禁用提交)大概率出错。稳妥做法是:用它做快速粗筛 + UI 提示,再配合轻量探测请求验证。
- 例如:监听
online后,立即fetch('/health', { method: 'HEAD', cache: 'no-store' })检查 API 可达性 - 超时设为 3–5 秒,失败则标记为“弱网”或“服务不可达”,而非简单当“离线”
- 避免用图片探测(
new Image().src=...),HTTP/2 下可能被复用连接掩盖真实问题
最常被忽略的一点:你在开发工具里切“Offline”模拟,只是禁了浏览器所有网络请求,和真实世界的“假在线”完全不是一回事——线上问题几乎全出在这里。

















