navigator.online 不可靠,仅反映网卡状态而非服务器可达性,需结合 online/offline 事件监听与 fetch 健康检查,并在离线时降级功能、本地持久化、防覆盖。

为什么 navigator.onLine 不能直接信,尤其对编辑器类应用
HTML 编辑器(比如基于 contenteditable 或 Monaco/CodeMirror 的富文本/代码编辑器)依赖实时同步、自动保存、协作光标等功能,一旦误判网络状态,轻则草稿丢失,重则覆盖他人修改。而 navigator.onLine 返回 true 时,常见现象是:fetch('/api/save') 卡住、报 TypeError: Failed to fetch,或返回 504 Gateway Timeout——这说明它只感知到“网卡通”,完全不反映服务器可达性、DNS 是否正常、代理是否存活。
更麻烦的是:某些浏览器(如旧版 Safari iOS)会恒返 true;PWA 场景下 Service Worker 可能缓存响应,导致 navigator.onLine === true 但实际请求全走 cache,掩盖真实断连。
- 别把
navigator.onLine当网络 ping 工具用 - 它初始化值只在页面加载那一刻有效,之后不会自动更新,必须配合事件监听
- 编辑器首次加载时若离线,
navigator.onLine可能仍为true(尤其 DevTools 离线模式未提前启用)
必须绑定的两个事件:online 和 offline
仅靠读取 navigator.onLine 做一次判断,编辑器无法响应用户中途断网。必须监听 window 上的 online 和 offline 事件,且要在脚本执行早期就注册——否则可能错过首次状态切换(比如用户打开页面时已离线,但事件不会回溯触发)。
推荐写法(兼容 Safari、Chrome、Edge):
const handleOnline = () => {
editor.setState({ isOnline: true });
// 触发一次健康检查,再决定是否重发草稿队列
};
const handleOffline = () => {
editor.setState({ isOnline: false });
// 暂停 autosave 定时器、禁用「发布」「同步」按钮
};
window.addEventListener('online', handleOnline);
window.addEventListener('offline', handleOffline);
// 清理(例如在 React useEffect cleanup 或页面卸载前)
// window.removeEventListener('online', handleOnline);
// window.removeEventListener('offline', handleOffline);
- 不要委托到
document或其他元素——这两个事件不冒泡,只能直接绑window - 避免在异步回调(如
setTimeout)里才绑定,否则可能漏掉初始状态变更 - 如果用了 Service Worker,别指望它影响
navigator.onLine值;它和 SW 是两套机制
怎么用 fetch 做二次验证,防止「假在线」坑编辑器
编辑器进入「在线」状态后,不能立刻执行同步逻辑。必须发起一次带超时的轻量探测,确认服务端真实可达。否则用户点「保存」后界面显示成功,其实请求早已失败,本地草稿被错误标记为「已提交」。
推荐使用 HEAD 请求 + AbortSignal.timeout():
async function checkServerReachable() {
try {
const res = await fetch('/health', {
method: 'HEAD',
cache: 'no-store',
signal: AbortSignal.timeout(2500)
});
return res.ok; // 仅 2xx 才算通过
} catch (e) {
return false;
}
}
- 路径选
/health(或你后端提供的无副作用探针端点),别用/或/api/status,避免触发 SSR 或鉴权逻辑 - 用
HEAD而非GET,减少带宽与服务端压力 - 超时设 2–3 秒:太短易误判(尤其移动端弱网),太长会让 UI 停滞感明显
- 只在
online事件触发后调用一次,不要轮询;离线期间无需验证
离线模式下编辑器该做什么,而不是「冻结」
检测到离线后,编辑器不该变灰禁用全部功能。真正要做的,是降级而非停止:
- 把「保存」按钮文字改为「已暂存(离线)」,并保持可点击(点击后弹 toast 提示「正在离线编辑,上线后自动同步」)
- 将每次内容变更序列化后存入
localStorage(键名建议含时间戳或哈希,避免冲突),而非只存最后一次 - 禁用实时协作功能(如光标共享、@ 提及),但允许本地评论/高亮等不需服务端的操作
- 列表页/资源树若依赖 API,切换为读取上次成功缓存的 JSON(可用
sessionStorage存,关页即丢,避免陈旧数据干扰) - 上线后,优先比对本地草稿哈希和服务端版本,避免静默覆盖
最易被忽略的一点:离线期间用户可能关闭标签页。必须在 beforeunload 钩子中主动保存当前快照,否则所有未显式「暂存」的编辑都会丢失——而用户根本没意识到自己处于离线状态。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











