教程 axios tutorial

请求失败重试策略

在复杂网络环境中(如移动端或弱网场景),请求可能因为超时、断网或服务器异常而失败。 为提升稳定性,Axios 可以通过重试机制在失败时自动重新发送请求。

一、为什么需要重试机制

常见导致请求失败的原因:

  • 网络波动或短暂中断;
  • 服务器临时过载;
  • 第三方 API 响应超时;
  • DNS 问题或负载均衡切换。

而这些问题往往是暂时性的,适当重试可以让请求成功率显著提升。

二、最简单的重试逻辑(手动实现)

js
import axios from "axios";

async function requestWithRetry(config, retryCount = 3, delay = 1000) {
  for (let i = 0; i < retryCount; i++) {
    try {
      const response = await axios(config);
      return response;
    } catch (error) {
      console.warn(`请求失败 [${i + 1}/${retryCount}]:`, error.message);
      if (i === retryCount - 1) throw error;
      await new Promise(res => setTimeout(res, delay)); // 延时后重试
    }
  }
}

使用示例:

js
requestWithRetry({ url: "/api/user", timeout: 2000 })
  .then(res => console.log("请求成功:", res.data))
  .catch(err => console.error("多次重试仍失败:", err.message));

三、结合拦截器实现自动重试

通过 Axios 拦截器,可以统一为所有请求添加重试逻辑:

js
const service = axios.create({
  baseURL: "/api",
  timeout: 5000
});

service.interceptors.response.use(
  res => res,
  async error => {
    const config = error.config;
    if (!config || config.__retryCount >= 3) {
      return Promise.reject(error);
    }

    config.__retryCount = (config.__retryCount || 0) + 1;
    console.log(`第 ${config.__retryCount} 次重试...`);

    await new Promise(res => setTimeout(res, 1000));
    return service(config);
  }
);

使用示例:

js
service.get("/data")
  .then(res => console.log("成功:", res.data))
  .catch(err => console.error("重试失败:", err.message));

四、使用第三方库 axios-retry

如果不想手动封装,可以直接使用官方社区维护的 axios-retry 插件。

安装

bash
npm install axios-retry

基本用法

js
import axios from "axios";
import axiosRetry from "axios-retry";

const instance = axios.create({ baseURL: "/api" });

axiosRetry(instance, {
  retries: 3, // 最大重试次数
  retryDelay: retryCount => retryCount * 1000, // 递增延时
  retryCondition: error => error.code === "ECONNABORTED" || error.response?.status >= 500
});

instance.get("/data")
  .then(res => console.log("成功:", res.data))
  .catch(err => console.error("最终失败:", err.message));

五、重试策略设计建议

场景 是否适合重试 建议策略
网络超时 ✅ 3 次,每次间隔 1 秒
服务器 500 错误 ✅ 2~3 次,带随机延迟
404 / 401 / 403 错误 ❌ 无需重试(逻辑错误)
文件上传 ⚠️ 建议分片重试,不整体重传
幂等操作(GET/HEAD) ✅ 可安全重试
非幂等操作(POST/PUT/DELETE) ⚠️ 谨慎使用,可能造成重复提交

六、结合指数退避算法(Exponential Backoff)

避免高频请求冲击服务器,可使用指数增长的延迟:

js
function exponentialDelay(retryCount) {
  return Math.pow(2, retryCount) * 1000; // 1s, 2s, 4s, 8s...
}

应用到 axios-retry:

js
axiosRetry(axios, {
  retries: 5,
  retryDelay: exponentialDelay
});

七、进阶:记录重试日志与监控上报

在生产环境中,可将失败与重试信息上报到日志系统或监控服务:

js
axios.interceptors.response.use(null, async error => {
  const cfg = error.config || {};
  cfg.__retryCount = (cfg.__retryCount || 0) + 1;

  if (cfg.__retryCount <= 3) {
    console.log(`[Retry] ${cfg.url} - attempt ${cfg.__retryCount}`);
    await new Promise(r => setTimeout(r, 1000));
    return axios(cfg);
  }

  // 上报日志系统
  sendLog({
    url: cfg.url,
    method: cfg.method,
    retries: cfg.__retryCount,
    message: error.message
  });

  return Promise.reject(error);
});

八、小结

Axios 的重试机制是提升前端网络稳定性的关键手段。 最佳实践:

  • 对**可恢复性错误(5xx、超时)**启用重试;
  • 控制重试次数与延迟,避免对服务器造成压力;
  • 使用 axios-retry 或拦截器实现全局自动重试;
  • 非幂等请求谨慎重试,避免数据重复提交。

通过科学的重试策略,Axios 可以在不稳定网络中保持高可用性与更流畅的用户体验。