断网恢复后自动重试失败请求的核心是监听网络状态变化、缓存可重试请求、健康检查确认恢复后串行重放。需区分幂等性,限制缓存数量与过期时间,避免并发雪崩,并通过统一请求拦截实现。

断网恢复后自动重试失败请求,核心思路是:监听网络状态变化 + 缓存失败请求 + 网络恢复时批量重放。不能只靠定时轮询或简单重试,需兼顾可靠性、重复提交防护和用户体验。
监听网络状态并识别“恢复”时刻
使用 navigator.onLine 和 online/offline 事件可感知基础连通性变化,但注意:onLine 为 true 不代表能访问目标服务器(比如防火墙拦截、DNS 失败、服务宕机)。因此“恢复”应定义为:网络从 offline 变为 online 且 至少一次健康检查(如 GET /health 或空 OPTIONS 请求)成功。
- 用
window.addEventListener('online', handler)捕获上线事件 - 触发后立即发一个轻量健康请求(带超时,如 3s),成功才视为真正可通信
- 避免在 offline 期间反复尝试健康检查,浪费资源
缓存失败请求(含参数、方法、headers)
不是所有请求都适合重试(如 POST/PUT 非幂等操作需谨慎),缓存前应做策略判断:
- 只缓存明确可重试的方法:GET、HEAD、OPTIONS;对 POST/PUT/DELETE,仅当业务确认幂等(如带唯一 idempotency-key)才缓存
- 记录完整请求信息:URL、method、body(序列化)、headers、timeout、credentials 等
- 用内存数组暂存即可;若需页面刷新后仍有效,可配合 localStorage + 序列化(注意 body 中函数或 Blob 无法保存)
- 设置最大缓存条数(如 20 条)和过期时间(如 5 分钟),防止堆积
恢复后按序重放,避免并发雪崩
一次性并发重试所有请求可能压垮服务端或触发限流。推荐串行+退避策略:
立即学习“Java免费学习笔记(深入)”;
- 用 async/await 链式执行,每条间隔 300–500ms,给服务端喘息空间
- 每次重试失败,记录失败次数;超过 3 次则丢弃该请求并通知用户(如 toast 提示“提交失败,请重试”)
- 对 GET 类请求,可加时间戳或随机 query 参数(如
?t=171xxxx)绕过强缓存 - 重放成功后,从缓存队列中移除,并触发对应 UI 更新(如刷新列表、填充表单)
补充:与 Axios/Fetch 封装结合更实用
不建议在每个 fetch 调用处手动加缓存逻辑。推荐统一拦截:
- 封装
request()函数,在 catch 块中判断 error 类型(TypeError: Failed to fetch或 status 0)→ 视为网络失败 → 进入缓存队列 - 全局维护一个
pendingRequests = [],online 回调中启动重试调度器 - 对已 resolve 的 Promise 不再重试,可用 Map 存储 request ID 防止重复加入
关键不在“重试”,而在“何时重、重什么、重几次”。做好状态判断、幂等控制和节流调度,就能让离线体验几乎无感。


















