不能仅依赖 navigator.onLine 判断重连,需用 fetch('/api/ping') 等主动探测并配 AbortController 设超时;真实断网信号是 TypeError: Failed to fetch 或 AbortError,重试必须基于此异常捕获。

网络中断时不能靠 navigator.onLine 判断是否重试,它在路由器断外网、DNS 故障、代理失效时仍返回 true;真实信号是 fetch() 或 XMLHttpRequest 抛出的 TypeError: Failed to fetch 或 AbortError。自动重试必须建立在这类异常被捕获的基础上,否则逻辑全失效。
fetch 上传失败后怎么触发重试
核心是封装上传函数并手动捕获网络异常,不能只依赖 HTTP 状态码:
-
fetch在真正断网、超时、连接被拒时会 reject 并抛出TypeError或AbortError,这是唯一可信的“网络中断”信号 - 必须给请求配
AbortSignal.timeout(3000)(Safari 16.4+ 支持),旧版需手写AbortController+setTimeout主动中断挂起请求 - 只对
TypeError和5xx响应重试;4xx(如400、401、413)说明是客户端问题,重试无意义 - 每次重试前检查
document.hidden,页面在后台(锁屏/切微信)时暂停,避免无效请求堆积
重试策略怎么设才不雪崩
移动端网络抖动频繁,硬塞 5 次重试会快速耗尽连接池、触发浏览器限流,甚至让用户误以为卡死:
- 推荐指数退避:第 1 次延迟
1000ms,第 2 次2000ms,第 3 次4000ms(即Math.pow(2, retryCount) * 1000) - 最大重试次数硬限制为
3,超限后不再自动重试,改为提示“网络不稳定,请稍后手动重试” - 每次重试前加随机偏移(如
+ Math.random() * 100),避免所有用户在同一秒重试造成流量尖峰 - 并发上传任务必须进队列管理,防止多个文件同时重试压垮客户端或服务端
上传失败后 input[type="file"] 怎么保持原文件
浏览器安全策略禁止 JS 赋值 input.value,所以“重试”不是恢复选择,而是复用原始 FileList:
立即学习“前端免费学习笔记(深入)”;
- 在
change或submit事件里立刻存下event.target.files,别等上传失败后再去读——那时可能已被清空 - 重试按钮点击后,直接调用独立上传函数
uploadFiles(fileList),传入之前保存的FileList -
FormData.append("file", file, file.name)必须带第三个参数(文件名),漏掉会导致后端(如 Express multer)解析失败 - 别在请求拦截器或封装层里无意调用
formData.delete("file")或覆盖原始File对象
最易被忽略的是:所有重试逻辑必须运行在 event.preventDefault() 拦截后的异步流程里。原生表单提交会立刻跳转或刷新,JS 全部中断——这点在移动端尤其致命,键盘弹起、屏幕旋转都可能意外触发 submit。



















