navigator.onLine仅反映浏览器网络接口连通性,非真实服务器可达性,需结合online/offline事件监听、请求级容错与本地缓存实现可靠离线体验。

直接用 navigator.onLine 判断网络状态并监听切换事件,就能让 UI 在离线时自动简化功能、提示用户、缓存操作,上线后平滑恢复——关键不在“检测”,而在“响应得当”。
理解 navigator.onLine 的真实行为
navigator.onLine 返回的是浏览器的网络接口连通性快照(如网卡是否启用、Wi-Fi 是否连接),不是 HTTP 请求可达性检测。它可能:
- 显示 true,但实际无法访问服务器(如内网断外网、DNS 故障、防火墙拦截);
- 显示 false,但本地资源(如 Service Worker 缓存、localStorage 数据)仍可使用。
因此不能单靠它决定“能否发请求”,而应把它作为用户网络环境变化的信号入口,配合请求失败兜底和缓存策略。
监听 online / offline 事件并更新 UI 状态
在页面初始化时绑定全局事件,用一个响应式状态(如 React 的 useState、Vue 的 ref 或纯 JS 的 class 属性)管理当前在线状态,并触发 UI 变化:
示例(原生 JS):
let isOnline = navigator.onLine;
<p>function updateUI() {
document.body.classList.toggle('offline', !isOnline);
document.getElementById('status-bar')?.textContent =
isOnline ? '在线' : '已离线,请检查网络';
}</p><p>window.addEventListener('online', () => {
isOnline = true;
updateUI();
});</p><p>window.addEventListener('offline', () => {
isOnline = false;
updateUI();
});</p><p>// 初始化
updateUI();
这样,状态栏、按钮禁用态、表单提交提示等都能实时响应。
离线时 UI 降级的实用策略
离线不等于“冻结”,而是转向更轻量、更鲁棒的交互模式:
-
禁用依赖网络的操作:如“提交表单”“刷新列表”“上传文件”按钮添加
disabled,同时用 tooltip 或旁注说明原因(如“离线中,内容将暂存本地”); -
启用本地缓存回显:用
localStorage或IndexedDB存储用户未提交的草稿,离线时自动加载并允许继续编辑; - 替换数据源:列表页从 API 切换为读取最近缓存的 JSON 数据(可用 Service Worker 预缓存或 runtime 缓存);
- 延迟同步机制:点击“保存”后,若检测到离线,把变更序列化存入队列,上线后由后台任务自动重试(建议加去重和失败计数,避免无限重发)。
增强可靠性:补充请求级容错
online/offline 事件有延迟(尤其从真离线恢复时),且无法捕获瞬时抖动。所以对关键请求,仍需:
- 所有 fetch 请求统一包装,catch 网络错误(
TypeError: Failed to fetch)并降级处理; - 设置较短 timeout(如 8s),避免长时间 pending 卡住 UI;
- 结合
navigator.onLine === false提前拒绝请求,减少无效尝试; - 在请求失败后,主动调用
setOfflineMode()并提示用户,比等待事件更及时。
这种“事件驱动 + 请求兜底”双保险,才能覆盖 Wi-Fi 连接但无外网、4G 信号弱、代理中断等复杂场景。

















