主题
请求失败重试策略
在复杂网络环境中(如移动端或弱网场景),请求可能因为超时、断网或服务器异常而失败。 为提升稳定性,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 可以在不稳定网络中保持高可用性与更流畅的用户体验。