body标签上的onoffline属性根本不会触发——它只是被浏览器忽略的无效写法,无论你怎么写、怎么测试,都不会弹出提示;唯一生效方式是window.addEventListener('offline', handler),且需在DOMContentLoaded或React useEffect首次执行时注册,并配合navigator.onLine初始化状态及fetch('/health')探测API可达性。

body 标签上的 onoffline 属性根本不会触发——它只是被浏览器忽略的无效写法,无论你怎么写、怎么测试,都不会弹出提示。
window.addEventListener('offline') 才是唯一生效的监听方式
所有现代浏览器只在 window 对象上派发 online 和 offline 事件,document 和 body 都不是合法目标。你写 <body onoffline="alert('断网了')">,控制台不报错,但 alert 永远不会出现。
- 必须用
window.addEventListener('offline', handler)注册监听器 - 不能用
window.onoffline = handler—— 这种属性赋值方式已被标准弃用,会覆盖其他模块(比如监控 SDK)注册的同名回调 - 注册时机要早:在
DOMContentLoaded或 React 的useEffect(() => {}, [])首次执行时就得绑上,否则可能漏掉首次离线事件
navigator.onLine 初始值必须手动读取
页面加载完成时,navigator.onLine 的值不会自动同步到 UI。它是个静态快照,不是响应式信号。如果你不主动读一次,用户打开页面时明明断网,UI 却显示“在线”。
- 初始化状态应写成:
const [isOnline, setIsOnline] = useState(navigator.onLine) - 紧接着绑定事件:
window.addEventListener('offline', () => setIsOnline(false))和window.addEventListener('online', () => setIsOnline(true)) - 注意:
file://协议下navigator.onLine恒为true,必须用 HTTP/HTTPS 环境测试
只靠 offline 事件显示提示,大概率误判
收到 offline 事件 ≠ 用户真的断网了,它延迟高、漏报多;而没收到事件也不代表网络正常——比如 DNS 污染、代理失效、后端挂了,navigator.onLine 仍返回 true,但表单提交必失败。
立即学习“前端免费学习笔记(深入)”;
- 移动端切后台再切回,
offline事件经常不触发,navigator.onLine值滞后 - 企业内网、虚拟机、多网卡环境下,拔网线几乎无法触发
offline,navigator.onLine保持true - 真正该检测的是“能否拿到
/health的 2xx 响应”,不是“操作系统有没有 IP 接口” - 推荐做法:在
offline回调里立即显示提示;在online回调里先发一次带AbortSignal.timeout(2000)的fetch('/health'),仅当成功才隐藏提示
最易被忽略的是:DevTools Network 面板的 Offline 开关才是唯一可靠测试手段。其他所有模拟方式(改 hosts、禁用 WiFi、拔线)在真实环境中都可能失效,导致你以为逻辑没问题,上线后用户大量报“提示不出现”。



















