2018年浏览器离线状态检测:替代offline.js的可靠方案
关于浏览器在线状态主动检测的方案建议
嘿,刚好对这个问题有研究,给你梳理下2018年兼容现代浏览器(包括移动端)的可行方案,不用着急自己造轮子!
现成靠谱方案,直接用就行
2018年有几个维护活跃、口碑不错的轻量库,专门解决navigator.onLine不可靠的问题,支持主动检测和状态变化事件:
is-online:这是当时最流行的选择之一,核心逻辑是定期发送HEAD请求到可靠的公共端点(比如Google的无内容返回接口),也支持配置成检测你自己的服务器。它内置了状态监听,能在网络状态切换时触发
online/offline事件,对移动端的兼容性做了优化,用法也很简单:// 单次检测在线状态 const isOnline = require('is-online'); isOnline().then(online => { console.log(`当前状态:${online ? '在线' : '离线'}`); }); // 持续监听状态变化 const stopListening = isOnline.onChange(online => { if (online) { console.log('网络恢复了!'); } else { console.log('网络断开了...'); } }); // 不需要监听时可以停止 stopListening();network-status:另一个轻量级的库,体积更小,支持自定义检测URL(推荐用你自己的API服务器,这样能同时验证是否能访问你的业务服务),同样支持状态变化事件,适合对包体积敏感的项目。
如果想自己实现,核心逻辑也不复杂
要是你有特殊需求(比如必须深度定制检测逻辑),自己开发也没什么难度,核心思路就是定期主动发送轻量级请求,结合状态对比来触发事件,关键注意这几点:
- 选好检测端点:优先用你自己的后端API(比如一个返回204的健康检查接口),这样能确保用户不仅连上网,还能正常访问你的服务;如果用公共端点,选稳定、无内容返回的地址,减少流量消耗。
- 控制检测频率:别太频繁,建议10-30秒检测一次,避免占用过多网络资源,移动端还要考虑流量成本。
- 处理超时和错误:设置合理的请求超时(比如5秒),请求失败或超时都判定为离线。
- 触发自定义事件:用浏览器的
EventTarget或者自定义事件发射器,当状态从在线变离线(或反之)时,触发对应的事件,方便业务代码监听。
给你个极简的实现示例:
class NetworkChecker { constructor(options = {}) { this.interval = options.interval || 15000; // 15秒检测一次 this.checkUrl = options.url || 'https://clients3.google.com/generate_204'; this.currentStatus = true; // 默认在线 this.eventTarget = new EventTarget(); this.start(); } async check() { try { await fetch(this.checkUrl, { method: 'HEAD', cache: 'no-store', mode: 'no-cors', signal: AbortSignal.timeout(5000) // 5秒超时 }); this.updateStatus(true); } catch (err) { this.updateStatus(false); } } updateStatus(newStatus) { if (newStatus !== this.currentStatus) { this.currentStatus = newStatus; const eventName = newStatus ? 'online' : 'offline'; this.eventTarget.dispatchEvent(new Event(eventName)); } } start() { this.check(); this.timer = setInterval(() => this.check(), this.interval); } stop() { clearInterval(this.timer); } on(event, handler) { this.eventTarget.addEventListener(event, handler); } off(event, handler) { this.eventTarget.removeEventListener(event, handler); } } // 使用示例 const checker = new NetworkChecker(); checker.on('online', () => alert('网络已恢复!')); checker.on('offline', () => alert('网络连接中断,请检查网络设置'));
总结
如果没有特殊定制需求,优先用现成库,它们已经处理了很多边缘情况(比如不同浏览器的fetch行为、移动端网络切换的延迟、请求重试逻辑等),省心又靠谱;如果需要深度定制,自己实现也很简单,核心就是主动请求+状态对比+事件触发。
内容的提问来源于stack exchange,提问作者Ryan Griggs
相关产品推荐
相关产品推荐

