Vue 3 请求重试应在响应拦截器错误分支中实现,通过独立配置retryCount/retryDelay、克隆请求配置、判断可重试错误类型、配合AbortController取消旧请求、指数退避延迟及UI反馈来确保可控性与健壮性。

Vue 3 中请求拦截器实现请求重试,关键不是“加个 retry 字段就完事”,而是要控制重试时机、避免无限循环、区分可重试错误,并与 AbortController 等机制协同。直接在响应拦截器中做逻辑判断 + 延迟重发,是最稳妥、最可控的方式。
响应拦截器中判断并触发重试
重试逻辑应放在响应拦截器的错误分支(即第二个参数),因为只有真正收到网络错误、超时或后端返回非预期状态码时,才需要决定是否重试。不能在请求发出前就预设重试——那会干扰正常流程。
- 为每个请求配置独立的重试参数,比如 retryCount(最大重试次数)和 retryDelay(延迟毫秒数),通过 config 自定义字段传入
- 首次失败时,检查 config.__retryCount 是否已存在;不存在则初始化为 0;若已达上限,直接 reject
- 未达上限时,递增计数器,用 setTimeout 延迟发起新请求(注意:需克隆 config,避免 signal 冲突或 headers 被污染)
- 推荐使用 axios(config) 而非 instance.request(),确保新请求仍走完整拦截器链
只对特定错误类型重试
不是所有错误都适合重试。弱网环境下,典型可重试场景包括:网络中断(ERR_NETWORK)、连接超时(ECONNABORTED)、502/503/504 网关类错误。而 401(未登录)、403(无权限)、400(参数错误)等业务错误不应重试。
- 通过 error.code 或 error.request.status 判断错误类型,避免盲目重试
- 可封装一个 isRetryableError(error) 工具函数,集中维护可重试的错误白名单
- 后端返回的 { code: 503, message: "服务暂时不可用" } 这类业务态错误,也可纳入重试条件(需前后端约定)
避免重复请求与资源泄漏
重试本身会带来并发风险:用户快速点击、页面未卸载导致多次重试叠加、旧请求 signal 未清理等。必须配合取消机制。
立即学习“前端免费学习笔记(深入)”;
- 每次重试前,调用 controller.abort() 清理上一次挂起的请求(如果还存在)
- 在请求拦截器中为每个请求生成唯一 key(如 method+url+params 序列化),用于去重和取消旧请求
- 组件 onUnmounted 时,主动调用 cancelRequest(key),防止内存泄漏和无效回调执行
- 重试次数建议限制在 2~3 次,retryDelay 从 300ms 开始指数退避(如 300 → 600 → 1200)
配合 Loading 与用户反馈
重试期间不能让用户以为“卡死”或“没反应”。需让 UI 层感知重试状态,例如显示“重试中(1/3)”提示。
- 可在 config 中增加 showRetryTip: true,并在拦截器中通过事件总线或 Pinia store 触发 UI 更新
- 首次失败可短暂保留 loading,重试开始后更新文字;全部失败再统一报错
- 避免连续弹出多个 ElMessage,改用单例 toast 或顶部进度条提示重试过程


















