navigator.online 返回 true 却没网是正常现象,因其仅监听系统网络接口状态,无法检测路由器断开、dns 故障或代理中断等深层问题。

navigator.onLine 返回 true 却没网?这是正常现象
navigator.onLine 不是 ping,也不查 DNS 或 HTTP 连通性。它只反映浏览器是否认为自己“在线”——本质是监听系统网络接口状态(比如 Windows 的网络适配器启用/禁用、macOS 的 Wi-Fi 开关),一旦系统报告“有网”,它就返回 true,哪怕路由器断了、DNS 挂了、或你连的是个没上外网的局域网热点。
常见错误现象:navigator.onLine === true 时发起 fetch() 却卡住或报 TypeError: Failed to fetch;或者页面显示“已联网”,但所有 API 都 504。
- 它不触发网络请求,所以极快、无跨域限制、无需权限
- 切换飞行模式、拔网线、关 Wi-Fi 通常能正确触发
online/offline事件 - 但重启路由器、DNS 故障、代理中断、防火墙拦截——这些它完全感知不到
怎么补足 navigator.onLine 的盲区?手动探测更可靠
真要判断“能否访问后端”,得发一个轻量 HTTP 请求。推荐用 fetch() 探测一个你可控的 endpoint,比如 /health 或直接复用登录接口的 OPTIONS 请求。
使用场景:页面加载后自动检查、用户点击“重试”时、表单提交前兜底校验。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 别用
GET /:首页可能被 CDN 缓存,返回 200 但实际服务已挂 - 加
?t=xxx时间戳或cache: 'no-store'防缓存 - 超时必须设(默认无超时),建议
signal: AbortSignal.timeout(5000) - 只关心网络层是否可达,不用等业务响应码,
response.ok或response.status是第二层判断
示例:
fetch('/health', { method: 'HEAD', cache: 'no-store', signal: AbortSignal.timeout(3000) })
监听 online/offline 事件要注意什么?
这两个事件由浏览器在系统网络状态变化时派发,但有延迟(尤其 macOS 切换热点)、且不会冒泡。最常踩的坑是:绑定太晚,错过初始状态;或没处理重复绑定。
- 务必在
DOMContentLoaded后立即绑定,别等 React/Vue mount 完 - 用
window.addEventListener('online', handler),不是document或其他元素 - 不要在组件卸载时忘记
removeEventListener,否则可能触发已销毁组件的逻辑 -
navigator.onLine初始值可能不准(如 Chrome 启动时未联网但返回true),首次应以事件触发后为准
兼容性与降级方案:老浏览器和 WebView 怎么办?
navigator.onLine 在 IE9+、所有现代浏览器都支持,但部分 Android WebView(尤其旧版 Cordova)会始终返回 true;iOS WKWebView 表现相对稳定。
- 不依赖它做关键流程控制(比如跳过登录直接进首页)
- 服务端接口必须自带容错:HTTP 状态码、超时、重试机制不能只靠前端判断
- Hybrid App 场景下,优先走原生桥接获取网络类型(WiFi/4G)和连通性,比 JS 层更准
复杂点从来不在“有没有网”,而在于“网在哪里断了”——DNS?TLS 握手?目标服务器?还是中间某个 CDN 节点?navigator.onLine 只回答第一个字。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










