拔掉网线后页面顶部的离线横幅没有出现,表单照常提交,等了三十秒才弹超时,navigator.onLine 读出来仍然是 true。乍看像缓存或者权限的锅,追下去往往不是。
async function probe() {
const c = new AbortController();
setTimeout(() => c.abort(), 3000);
return fetch('/ping', {signal: c.signal, cache: 'no-store'}).then(r => r.ok).catch(() => false);
}
追下去是这么回事:onLine 只反映网卡有没有连上,路由器通不通、上游能不能出网它都不知道。连着内网但出口断了,这个值一样是 true,拿它判断离线并不可靠。
「navigator.onLine 误判」相关的日志我一般连着看前后五分钟,单看一条报错经常判断不出是哪一步失败。接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。
偶发问题先统计频率,一小时几次和一天一次,查法完全不同。改完顺手把文档补一句,省得下次自己重新推一遍。
具体做法是,用 fetch 请求一个小的健康检查接口,超时设三秒,失败才认定离线;同时监听 online 和 offline 事件,事件触发后再补一次探测;横幅状态用探测结果驱动,别直接绑 onLine。
验收就看一点,断网后三秒内出现离线提示,恢复网络后提示自动消失,不用手动刷新页面。
