应结合 navigator.online 初始化状态、offline 事件监听与轻量 fetch 探测,构建可靠离线检测机制,并结构化标记离线数据以支持精准同步。

不能只靠 navigator.onLine 做 UI 降级或数据标记,它只反映系统网络接口是否启用,不表示业务可达。必须用它配合 offline 事件做快速感知,并叠加轻量探测验证真实连通性,才能安全触发降级逻辑。
用 navigator.onLine 初始化状态,避免首屏误判
页面加载时立即读取 navigator.onLine,作为初始网络状态依据。这能防止用户刚打开页面就看到错误提示,或错过首次离线状态。
- 直接赋值给 React state、Vue ref 或全局变量,例如:
const [isOnline, setIsOnline] = useState(navigator.onLine) - 不要在初始化阶段就执行 fetch 探测——会增加首屏延迟,且无必要
- 若初始为
false,可立即禁用提交按钮、灰化表单控件、显示「离线中」提示条
监听 offline 事件,触发 UI 降级动作
offline 是唯一可靠的通知入口,它由浏览器在系统级断网(如拔网线、关 Wi-Fi)后主动触发,虽有 1–3 秒延迟,但语义明确。
- 必须绑定在
window上:window.addEventListener('offline', handleOffline) - 在回调中执行 UI 降级:隐藏实时刷新按钮、停用搜索自动补全、切换为本地缓存列表、将输入框设为只读(保留草稿)
- 对关键操作(如表单提交)打上「待同步」标记:在 localStorage 中写入带时间戳的未发送数据包,并记录
status: "pending"
用 fetch 探测兜底,防止 false positive
offline 事件不会在 DNS 失败、代理中断、内网不通外网等场景触发,此时 navigator.onLine === true 却实际不可用。需主动探测确认。
- 选一个同域、返回 HTTP 204 的轻量接口(如
/health),避免跨域和缓存干扰 - 搭配
AbortController设 3 秒超时,捕获TypeError(网络中断)和AbortError(超时) - 仅当
offline事件触发 且 探测失败时,才执行强降级(如弹出 Toast、覆盖半透明提示层) - 探测失败后,可将当前页面所有 API 请求拦截并转为队列暂存,等待恢复后重放
数据标记要带上下文,方便后续同步
离线时产生的数据不是简单“存起来”,而是需要结构化标记,支撑恢复后的精准同步与冲突处理。
- 每条离线数据应包含:
id(客户端生成 UUID)、timestamp(毫秒时间戳)、type(create/update/delete)、payload(原始内容)、origin(来源页面或模块) - 使用 IndexedDB 存储比 localStorage 更稳妥,支持事务与大容量
- 同步前先比对服务端最新版本号或 ETag,避免覆盖他人修改;冲突时保留本地副本并提示用户选择
- 同步成功后清除标记,并更新 UI 状态(如把「已离线保存」改为「已同步」)










