Navigator.onLine 不可靠,需配合 fetch('/favicon.ico') 主动探测;它仅反映系统网络接口状态,无法识别 DNS 失败、代理中断等真实离线场景,而 fetch 可捕获 TypeError 和 AbortError,结合 cache: 'no-store' 与超时控制更准确。

Navigator.onLine 不可靠,不能单独用于判断真实网络连通性。 它只反映浏览器认为的“离线/在线”状态,依赖操作系统网络接口通知,会漏判、误报,比如 Wi-Fi 已连接但 DNS 失败、代理中断、防火墙拦截时仍返回 true。
Navigator.onLine 的行为和触发时机
这个属性是只读布尔值,初始值取决于页面加载时系统网络栈状态。它会在浏览器检测到系统级网络接口切换(如断开 Wi-Fi、拔掉网线)时触发 online 或 offline 事件,但不主动探测远程可达性。
- Windows/macOS/Linux 上,它监听的是 OS 的「网络适配器状态」,不是「能否访问互联网」
- Chrome 和 Firefox 行为基本一致;Safari 在某些 macOS 版本中甚至不会触发
offline事件(例如仅禁用 Wi-Fi 而未关闭硬件) - 在 PWA 中,Service Worker 可能缓存响应,导致
fetch()成功但实际已断网 —— 此时navigator.onLine仍为true
为什么 fetch('/favicon.ico') 是更实用的检测方式
比起依赖系统信号,主动发一个轻量 HTTP 请求更能反映真实连通能力。选 /favicon.ico 是因为它通常体积小、无业务逻辑、服务器默认存在,且跨域风险低(同源下可直接用)。
- 必须设置
cache: 'no-store'防止从缓存返回 200,误判为在线 - 超时需手动控制:
AbortSignal.timeout(3000)(现代浏览器支持),或封装Promise.race()+setTimeout - 404 不代表离线(可能是服务端没配 favicon),应优先关注
TypeError(网络拒绝、DNS 失败)和AbortError - 避免高频轮询:建议首次加载后每 15–30 秒检测一次,或监听
online/offline事件后再触发验证请求
兼容旧版浏览器的兜底方案
IE11 或 Android 4.4 WebView 等环境不支持 AbortSignal.timeout,需降级处理:
立即学习“前端免费学习笔记(深入)”;
function checkNetwork() {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 3000);
return fetch('/favicon.ico', {
method: 'HEAD',
cache: 'no-store',
signal: controller.signal
}).then(res => {
clearTimeout(timeoutId);
return res.ok || res.status === 404; // 404 视为网络可达
}).catch(err => {
clearTimeout(timeoutId);
return err.name === 'AbortError' || err.name === 'TypeError';
});
}
- 用
HEAD方法减少带宽消耗 - 显式清除
timeoutId,防止内存泄漏 - 不依赖
navigator.onLine做前置判断 —— 它可能为false但 fetch 却成功(如本地开发服务器运行中)
真正可靠的网络状态判断永远需要组合策略:用 navigator.onLine 做快速粗筛 + 用可控 fetch 做细粒度验证 + 根据业务容忍度设定重试逻辑。别让「看起来在线」变成用户点击按钮后才暴露的错误。



















