Article

异步请求库 axios 使用

更新于:2026-07-11

一、初识 Axios

1.1 什么是 Axios

概念名称说明注意事项
Axios基于 Promise 的 HTTP 客户端,可用于浏览器和 Node.js 环境,用于发送异步 HTTP 请求。不是原生 JavaScript API,需通过 npm 或 CDN 引入。
HTTP 客户端允许前端应用与后端服务器通过 HTTP 协议进行数据交互(如获取数据、提交表单等)。主要用于与 RESTful API 或 GraphQL 接口通信。
PromiseAxios 所有请求返回 Promise 对象,支持 .then()/.catch()async/await 语法。需理解 Promise 基本用法以正确处理异步操作。

1.2 Axios 的核心特性

特性名称说明注意事项
浏览器支持在浏览器中发送 XMLHttpRequests 请求。支持所有现代浏览器,包括 IE11(需 polyfill)。
Node.js 支持在服务器端发送 http 请求。使用 Node.js 的内置 http 模块,无需额外依赖。
请求/响应拦截提供拦截器机制,可在请求发出前或响应返回后统一处理。常用于添加 Token、日志记录、错误统一处理等。
自动转换数据自动将请求数据序列化为 JSON,自动解析响应数据为 JSON。默认行为,可通过配置覆盖。
客户端防御 XSRF可配置以防止跨站请求伪造攻击。需后端配合设置 cookie 和验证机制。
取消请求支持使用 AbortController API 取消请求。已弃用旧的 CancelToken 方式,推荐使用 AbortController
请求进度监控支持上传和下载进度事件监听。仅在浏览器环境有效,Node.js 不支持。

1.3 浏览器与 Node.js 环境支持

环境类型支持情况注意事项
浏览器完全支持,基于 XMLHttpRequestfetch(适配器实现)需注意跨域问题(CORS),需后端配置响应头。
Node.js完全支持,基于内置 http 模块可用于服务端渲染(SSR)、脚本任务、微服务调用等场景。
React Native支持,视为浏览器环境运行可正常使用所有浏览器特性。
Web Workers支持有限不支持某些 DOM 相关功能(如 FormData),需注意兼容性。
Electron主进程(Node)和渲染进程(浏览器)均支持根据运行上下文自动选择适配器。

二、快速上手

2.1 安装与引入方式(npm / CDN)

方式语法用途代码示例注意事项
npm 安装npm install axios在 Node.js 或前端构建项目中安装 Axiosnpm install axios推荐方式,便于版本管理和 tree-shaking。
import axios from 'axios';
yarn 安装yarn add axios同上,使用 Yarn 包管理器yarn add axios功能等价于 npm 安装。
import axios from 'axios';
CDN 引入在 HTML 中通过 script 标签引入<script src="https://unpkg.com/axios/dist/axios.min.js"></script>全局暴露 axios 变量,适合简单项目或学习使用。
ES6 模块导入import axios from 'axios'在支持模块化的环境中导入import axios from 'axios';适用于 Vue、React、Webpack/Vite 项目。
CommonJS 导入const axios = require('axios')在 Node.js 或不支持 ES6 模块的环境中使用const axios = require('axios');传统 Node.js 项目常用方式。

2.2 创建第一个 axios 实例

类别方法名称语法用途代码示例注意事项
创建实例axios.create([config])axios.create({ ...配置项 })创建一个独立的 axios 实例,拥有自定义配置(如 baseURLheaders 等),用于特定用途(如不同 API 服务)。const api = axios.create({
baseURL: 'https://api.example.com',
timeout: 5000,
headers: { 'Content-Type': 'application/json' }
});

api.get('/users'); // 使用该实例
- 实例之间配置互不影响。
- 适合多 API 源、环境隔离。
- 可创建多个实例用于不同服务。
全局默认配置axios.defaultsaxios.defaults.属性 = 值设置所有 axios 请求的默认行为(如默认 baseURLtimeoutheaders)。axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.timeout = 3000;
axios.defaults.headers.common['Authorization'] = 'Bearer token';

axios.get('/users'); // 自动使用默认配置
- 影响所有 axios 请求(包括 axios.getaxios.post 等)。
- 不推荐在库中使用,可能影响调用方。
- 可被实例配置覆盖。

2.3 发送第一个 GET 请求

方法语法用途代码示例注意事项
axios.getaxios.get(url[, config])向指定 URL 发送 GET 请求获取数据axios.get('/user', {
params: { id: 123 }
})
.then(response => {
console.log(response.data);
});
params 用于拼接查询字符串,如 ?id=123
axiosaxios(config)通用请求方法,配置 method'get'axios({
method: 'get',
url: '/user',
params: { id: 123 }
})
.then(response => {
console.log(response.data);
});
更灵活,适合复杂配置场景。

2.4 发送第一个 POST 请求

方法语法用途代码示例注意事项
axios.postaxios.post(url, data[, config])向指定 URL 发送 POST 请求提交数据axios.post('/user', {
name: 'John',
age: 30
})
.then(response => {
console.log(response.data);
});
第二个参数为请求体数据,自动序列化为 JSON。
axiosaxios(config)通用请求方法,配置 method'post'axios({
method: 'post',
url: '/user',
data: { name: 'John', age: 30 }
})
.then(response => {
console.log(response.data);
});
适用于需要精细控制请求头、超时等配置的场景。

2.5 基本请求方法别名使用

方法别名语法用途代码示例注意事项
axios.getaxios.get(url[, config])发送 GET 请求axios.get('/api/users')
.then(res => console.log(res.data));
用于读取资源。
axios.deleteaxios.delete(url[, config])发送 DELETE 请求axios.delete('/api/users/1')
.then(res => console.log(res.data));
用于删除资源,可携带 params
axios.headaxios.head(url[, config])发送 HEAD 请求axios.head('/api/users/1')
.then(res => console.log(res.headers));
获取响应头信息,不返回响应体。
axios.optionsaxios.options(url[, config])发送 OPTIONS 请求axios.options('/api/users')
.then(res => console.log(res.headers));
用于预检请求(CORS)或获取接口支持的方法。
axios.postaxios.post(url, data[, config])发送 POST 请求axios.post('/api/users', { name: 'Tom' })
.then(res => console.log(res.data));
用于创建资源。
axios.putaxios.put(url, data[, config])发送 PUT 请求axios.put('/api/users/1', { name: 'Tom' })
.then(res => console.log(res.data));
用于完整更新资源。
axios.patchaxios.patch(url, data[, config])发送 PATCH 请求axios.patch('/api/users/1', { name: 'Tom' })
.then(res => console.log(res.data));
用于部分更新资源。

注意:所有别名方法均返回 Promise,可链式调用 .then/.catch 或使用 async/await

三、Axios 请求配置详解

请求配置优先级:请求配置 > 实例配置 > 全局配置

3.1 全局配置(axios.defaults)

配置项语法用途代码示例注意事项
axios.defaults.baseURLaxios.defaults.baseURL = 'url'设置所有请求的默认基础 URLaxios.defaults.baseURL = 'https://api.example.com';
axios.get('/users'); // 实际请求: https://api.example.com/users
影响所有后续请求,包括实例和别名方法。
axios.defaults.timeoutaxios.defaults.timeout = 毫秒数设置请求超时时间axios.defaults.timeout = 5000; // 5秒超时超时后 Promise 被 reject,需错误处理。
axios.defaults.headersaxios.defaults.headers['Header-Name'] = 'value'设置默认请求头axios.defaults.headers['Authorization'] = 'Bearer token';
axios.defaults.headers.post['Content-Type'] = 'application/json';
可按方法(get/post/put 等)设置特定头。
axios.defaults.transformRequestaxios.defaults.transformRequest = [function]自定义请求数据序列化axios.defaults.transformRequest = [function(data) {
return JSON.stringify(data);
}];
通常用于修改 POST/PUT 数据格式。
axios.defaults.transformResponseaxios.defaults.transformResponse = [function]自定义响应数据解析axios.defaults.transformResponse = [function(data) {
return JSON.parse(data);
}];
可用于预处理响应体(如加解密)。

3.2 自定义实例配置(axios.create)

方法语法用途代码示例注意事项
axios.createaxios.create(config)创建一个具有自定义配置的 axios 实例const instance = axios.create({
baseURL: 'https://api.example.com/v1',
timeout: 3000,
headers: { 'X-Custom-Header': 'foobar' }
});
instance.get('/users');
实例独立于全局配置,适合多接口域名项目。
实例方法调用instance.request(config)使用实例发送请求instance.post('/login', {
username: 'admin'
});
支持 .get.post.put 等所有别名方法。
多实例管理多个 create 调用管理不同服务的请求配置const userApi = axios.create({ baseURL: '/users' });
const orderApi = axios.create({ baseURL: '/orders' });
避免配置冲突,提升代码可维护性。

3.3 请求配置项(config)完整参数说明

配置项类型用途代码示例注意事项
urlstring请求地址(必填){ url: '/user' }若使用实例,会与 baseURL 拼接。
methodstring请求方法{ method: 'post' }默认为 GET。
baseURLstring基础 URL{ baseURL: 'https://api.example.com' }优先级高于全局 defaults
headersobject自定义请求头{ headers: { 'Authorization': 'Bearer x' } }可覆盖默认 headers。
paramsobjectURL 查询参数{ params: { id: 123 } }?id=123仅用于 GET、HEAD 等方法。
dataany请求体数据(POST/PUT/PATCH){ data: { name: 'John' } }自动序列化为 JSON(默认)。
timeoutnumber超时时间(毫秒){ timeout: 5000 }超时后请求中断,Promise reject。
withCredentialsboolean是否携带跨域凭证(Cookie){ withCredentials: true }需后端设置 Access-Control-Allow-Credentials
responseTypestring响应数据类型{ responseType: 'blob' }可选:'json''text''document''stream''arraybuffer'。下载文件时常用 blobarraybuffer
onUploadProgressfunction上传进度回调{ onUploadProgress: (progressEvent) => {
const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total);
console.log(percent);
} }
仅浏览器环境有效。
onDownloadProgressfunction下载进度回调{ onDownloadProgress: (progressEvent) => {
console.log(progressEvent.loaded);
} }
仅浏览器环境有效。
transformRequestfunction | array请求数据预处理{ transformRequest: [(data) => JSON.stringify(data)] }可用于加密或格式转换。
transformResponsefunction | array响应数据后处理{ transformResponse: [(data) => JSON.parse(data)] }可用于统一数据结构处理。
validateStatusfunction自定义状态码成功判断{ validateStatus: (status) => status < 400 }默认只将 2xx 视为成功。

四、处理响应与错误

4.1 响应结构解析

属性名类型说明代码示例注意事项
dataany服务器返回的数据(已解析)axios.get('/user').then(res => {
console.log(res.data); // 如: { id: 1, name: 'John' }
});
默认自动 JSON 解析,无需手动 JSON.parse
statusnumberHTTP 状态码res.status // 例如: 200, 404, 500用于判断请求结果类型。
statusTextstring状态码文本描述res.statusText // 例如: 'OK', 'Not Found'一般用于调试或日志记录。
headersobject响应头信息res.headers['content-type'] // 获取 content-type所有键名小写。
configobject请求时使用的配置res.config.url // 查看原始请求 URL便于调试和重试请求。
requestXMLHttpRequest | ClientRequest生成此响应的原始请求对象res.request // 浏览器中为 XMLHttpRequest 实例高级用法,如调试网络问题。

4.2 错误类型与错误对象结构

错误类型触发条件error 对象关键属性示例说明注意事项
请求配置错误配置项不合法(如 timeout 为负数)error.messageerror.codeError: timeout value must be a non-negative integer通常在请求发起前抛出。
网络错误无网络、DNS 失败、连接中断error.messageerror.requestNetwork Error
error.request 存在,但 error.responseundefined
error.response 不存在。
超时错误请求超时error.messageerror.code = 'ECONNABORTED'timeout of 1000ms exceeded可通过 error.code 判断是否为超时。
服务器错误服务器返回 4xx/5xx 状态码error.responseerror.response.statuserror.response.status = 404
error.response.data = { error: 'Not Found' }
error.response 存在,可获取详细信息。
取消请求用户主动取消请求error.messageerror.name = 'CanceledError'Cancel
error.name === 'CanceledError'
需使用 AbortController 触发。

4.3 使用 try-catch 处理错误

方法语法用途代码示例注意事项
async/await + try-catchtry { await axios() } catch (error) {}在异步函数中同步方式处理错误async function fetchUser() {
try {
const res = await axios.get('/user/1');
console.log(res.data);
} catch (error) {
if (error.response) {
console.error('服务器错误:', error.response.status);
} else if (error.request) {
console.error('网络错误');
} else {
console.error('配置错误:', error.message);
}
}
}
推荐现代项目使用,代码更清晰。
错误类型判断if (error.response) / else if (error.request)区分不同错误类型if (error.response) { /* 服务器返回了错误 */ }
else if (error.request) { /* 请求发出但无响应 */ }
else { /* 其他错误(如配置错误) */ }
必须按此顺序判断,避免误判。

4.4 使用 .catch() 处理错误

方法语法用途代码示例注意事项
.catch() 链式调用axios().catch(error => {})Promise 风格错误处理axios.get('/user/1')
.then(res => console.log(res.data))
.catch(error => {
if (error.response) {
console.error('状态码:', error.response.status);
} else {
console.error('请求失败:', error.message);
}
});
传统方式,适用于不支持 async/await 的环境。
全局错误捕获axios().catch(globalErrorHandler)封装统一错误处理函数function handleError(error) {
if (error.response?.status === 401) {
alert('登录已过期');
}
}
axios.get('/data').catch(handleError);
提升代码复用性,避免重复逻辑。
finally 清理资源.finally(() => {})无论成功失败都执行axios.get('/data')
.then(res => { /* 处理数据 */ })
.catch(err => { /* 处理错误 */ })
.finally(() => {
loading = false;
});
适合关闭加载动画、释放资源等操作。

五、拦截器的使用

5.1 请求拦截器(Interceptors.request)

方法语法用途代码示例注意事项
axios.interceptors.request.useaxios.interceptors.request.use(onFulfilled, onRejected)在请求发送前统一处理配置axios.interceptors.request.use(
config => {
config.headers.Authorization = 'Bearer ' + getToken();
config.startTime = Date.now();
return config;
},
error => {
return Promise.reject(error);
}
);
必须返回 config,否则请求将被阻断。
添加请求日志同上记录请求信息用于调试config.headers['X-Request-Start'] = Date.now();
console.log('请求发出:', config.url);
可用于性能监控。
统一设置 Token同上自动附加认证信息if (config.url !== '/login') {
config.headers.Authorization = 'Bearer ' + localStorage.getItem('token');
}
避免在每个请求中重复写。

5.2 响应拦截器(Interceptors.response)

方法语法用途代码示例注意事项
axios.interceptors.response.useaxios.interceptors.response.use(onFulfilled, onRejected)在响应返回后统一处理结果或错误axios.interceptors.response.use(
response => {
const duration = Date.now() - response.config.startTime;
console.log(请求耗时: ${duration}ms);
return response;
},
error => {
if (error.response?.status === 401) {
window.location.href = '/login';
}
return Promise.reject(error);
}
);
成功回调接收响应对象,失败回调接收错误对象。
统一错误处理onRejected 回调集中处理 401、403、500 等状态码if (error.response?.status === 401) {
clearAuth();
router.push('/login');
} else if (error.response?.status === 500) {
alert('服务器内部错误');
}
避免在每个 .catch 中重复判断。
响应数据预处理onFulfilled 回调统一提取 data 字段或转换格式return {
data: response.data.result,
code: response.data.code
};
可标准化不同接口返回结构。

5.3 移除拦截器与添加多个拦截器

方法语法用途代码示例注意事项
添加多个拦截器多次调用 use按顺序执行多个处理逻辑axios.interceptors.request.use(config => {
config.headers.A = '1';
return config;
});
axios.interceptors.request.use(config => {
config.headers.B = '2';
return config;
});
执行顺序为注册顺序(先进先出)。
移除拦截器const myInterceptor = axios.interceptors.xxx.use(...);
axios.interceptors.xxx.eject(myInterceptor);
动态取消某个拦截器const reqInterceptor = axios.interceptors.request.use(config => {
config.custom = true;
return config;
});
axios.interceptors.request.eject(reqInterceptor);
eject 后该拦截器不再生效。
拦截器存储与复用变量保存引用在组件销毁时移除(如 Vue/React)// Vue 中
created() {
this.interceptor = axios.interceptors.response.use(...);
}
beforeUnmount() {
axios.interceptors.response.eject(this.interceptor);
}
防止内存泄漏或重复注册。

六、高级用法

6.1 并发请求:axios.all 与 axios.spread

方法语法用途代码示例注意事项
axios.allaxios.all([promise1, promise2])并发执行多个请求,全部成功才 resolveaxios.all([
axios.get('/users'),
axios.get('/posts')
]).then(responses => {
const users = responses[0].data;
const posts = responses[1].data;
});
类似 Promise.all,任一失败则整体 reject。
axios.spreadaxios.spread(callback)将数组参数展开为多个参数传入回调axios.all([
axios.get('/users'),
axios.get('/posts')
]).then(
axios.spread((userRes, postRes) => {
console.log(userRes.data, postRes.data);
})
);
需配合 axios.all 使用,提升可读性。
替代方案(推荐)Promise.all原生方式实现并发try {
const [userRes, postRes] = await Promise.all([
axios.get('/users'),
axios.get('/posts')
]);
} catch (error) { /* 处理错误 */ }
axios.all 已不推荐,建议使用 Promise.all

6.2 取消请求(CancelToken 已废弃 / AbortController)

方法语法用途代码示例注意事项
AbortController(推荐)new AbortController()标准化取消请求方式const controller = new AbortController();
axios.get('/data', {
signal: controller.signal
})
.catch(err => {
if (axios.isCancel(err)) {
console.log('请求被取消:', err.message);
}
});
// 取消请求
controller.abort();
signalAbortController 的核心属性。
取消时传递消息controller.abort('原因')自定义取消原因controller.abort('用户跳转页面');
if (axios.isCancel(err)) {
console.log(err.message); // 输出: "用户跳转页面"
}
错误对象 err.message 即为传入的消息。
axios.isCancelaxios.isCancel(error)判断错误是否为取消操作引起if (axios.isCancel(error)) {
console.log('请求已取消');
}
必须使用此方法判断,不能直接比较。
CancelToken(已废弃)axios.CancelToken.source()旧版取消机制(不推荐)const source = axios.CancelToken.source();
axios.get('/data', { cancelToken: source.token });
source.cancel('取消');
新项目请使用 AbortController

6.3 上传文件与下载进度监控

方法/配置语法用途代码示例注意事项
onUploadProgressconfig.onUploadProgress监听文件上传进度axios.post('/upload', formData, {
headers: { 'Content-Type': 'multipart/form-data' },
onUploadProgress: progressEvent => {
const percent = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
console.log(${percent}% 上传完成);
}
});
仅浏览器环境有效,Node.js 不支持。
onDownloadProgressconfig.onDownloadProgress监听文件下载进度axios.get('/large-file.pdf', {
responseType: 'blob',
onDownloadProgress: progressEvent => {
console.log(已下载: ${progressEvent.loaded} 字节);
}
});
适用于大文件下载场景。
FormData 上传new FormData()构造表单数据上传文件const formData = new FormData();
formData.append('file', fileInput.files[0]);
axios.post('/upload', formData);
必须设置 Content-Typemultipart/form-data(axios 会自动设置)。

6.4 自定义适配器与 mock 数据

方法语法用途代码示例注意事项
自定义适配器adapter: function (config) {}替换默认的 HTTP 请求逻辑const mockAdapter = config => {
return new Promise(resolve => {
setTimeout(() => {
resolve({
data: { id: 1, name: 'Mock User' },
status: 200,
statusText: 'OK',
headers: {},
config
});
}, 500);
});
};
axios.get('/user', { adapter: mockAdapter });
用于测试、离线模式或集成非标准网络库。
全局替换适配器axios.defaults.adapter设置默认适配器axios.defaults.adapter = mockAdapter;影响所有后续请求,慎用。
使用 axios-mock-adapter第三方库更强大的 mock 方案import MockAdapter from 'axios-mock-adapter';
const mock = new MockAdapter(axios);
mock.onGet('/users').reply(200, [{ id: 1, name: 'John' }]);
推荐用于单元测试或开发环境 mock。
适配小程序请求adapter 调用 wx.request在微信小程序中使用 axiosadapter: config => {
return new Promise((resolve, reject) => {
wx.request({
url: config.url,
method: config.method,
data: config.data,
success: resolve,
fail: reject
});
});
}
需自行封装兼容性逻辑。

七、实际项目中的最佳实践

7.1 封装统一请求模块

方法/配置语法用途代码示例注意事项
创建 axios 实例axios.create(config)隔离配置,避免污染全局const service = axios.create({
baseURL: process.env.VUE_APP_API_BASE_URL,
timeout: 10000
});
推荐项目中始终使用实例而非全局 axios
封装 request 函数export function request(config) {}提供统一调用接口export function request(options) {
return service(options)
.then(res => res.data)
.catch(err => {
throw err;
});
}
统一处理响应 data 层级,调用端直接获取数据。
按模块导出 APIexport const userApi = { get, post }结构化管理接口export const userApi = {
getList: () => request({ url: '/users', method: 'get' }),
getById: (id) => request({ url: /users/${id}, method: 'get' })
};
提升可维护性,便于团队协作。
环境变量区分 baseURL使用 .env 文件不同环境(dev/test/prod)请求不同地址# .env.development
VUE_APP_API_BASE_URL=https://dev-api.example.com

# .env.production
VUE_APP_API_BASE_URL=https://api.example.com
避免硬编码,提升安全性。

7.2 状态码统一处理与提示

方法语法用途代码示例注意事项
响应拦截器中判断 statusresponse.status统一处理常见状态码service.interceptors.response.use(
response => {
return response;
},
error => {
const { status } = error.response;
switch (status) {
case 400:
alert('请求参数错误');
break;
case 403:
alert('权限不足');
break;
case 404:
alert('请求资源不存在');
break;
case 500:
alert('服务器内部错误');
break;
default:
alert('网络异常');
}
return Promise.reject(error);
}
);
避免在业务代码中重复写提示逻辑。
自定义业务状态码处理error.response.data.code处理后端自定义 code(如 { code: 1001, msg: '登录失效' }if (error.response?.data?.code === 1001) {
alert('登录已过期,请重新登录');
localStorage.removeItem('token');
location.href = '/login';
}
前后端需约定 code 含义。
错误提示可配置化引入 message/toast 组件使用 UI 库提示(如 Element Plus、Ant Design)import { Message } from 'element-plus';
Message.error('请求失败');
alert 更美观,支持自动关闭。

7.3 Token 认证与自动刷新

方法语法用途代码示例注意事项
请求拦截器附加 Tokenconfig.headers.Authorization自动携带 Tokenservice.interceptors.request.use(config => {
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = Bearer ${token};
}
return config;
});
所有请求自动附加,无需手动设置。
响应拦截器处理 401error.response.status === 401检测 Token 失效service.interceptors.response.use(
response => response,
error => {
if (error.response?.status === 401) {
localStorage.removeItem('token');
location.href = '/login';
}
return Promise.reject(error);
}
);
防止未授权请求反复尝试。
Token 自动刷新机制refresh token在 Token 过期后获取新 Tokenlet isRefreshing = false;
let refreshSubscribers = [];

function subscribeTokenRefresh(cb) {
refreshSubscribers.push(cb);
}

service.interceptors.response.use(
response => response,
async error => {
const { status } = error.response;
if (status === 401 && !error.config._retry) {
if (!isRefreshing) {
isRefreshing = true;
const newToken = await refreshTokenAPI();
localStorage.setItem('token', newToken);
refreshSubscribers.forEach(cb => cb(newToken));
refreshSubscribers = [];
isRefreshing = false;
}
const retryConfig = error.config;
retryConfig._retry = true;
retryConfig.headers.Authorization = Bearer ${newToken};
return service(retryConfig);
}
return Promise.reject(error);
}
);
防止多个请求同时触发刷新,需加锁(isRefreshing)和队列机制。
避免死循环添加 _retry 标志防止刷新后再次进入 401 逻辑error.config._retry = true;
return service(error.config);
必须标记已重试,否则会无限循环。

7.4 超时设置与重试机制

方法语法用途代码示例注意事项
全局超时设置timeout: 毫秒数防止请求长时间挂起const service = axios.create({
timeout: 10000 // 10秒超时
});
根据业务需求合理设置,过短影响正常请求。
动态超时config.timeout按接口设置不同超时时间request({
url: '/large-data',
method: 'get',
timeout: 30000 // 30秒
});
大文件上传/下载需更长超时。
请求重试机制递归 + 次数限制网络波动时自动重试function requestWithRetry(config, retries = 3) {
return service(config).catch(async error => {
if (retries > 0 && !error.response) {
return requestWithRetry(config, retries - 1);
}
throw error;
});
}
避免对 POST 等非幂等操作重试,防止重复提交。
指数退避重试setTimeout + 延迟递增避免频繁重试加剧服务器压力const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
await delay(1000 * (4 - retries));
更友好的重试策略,适用于生产环境。
重试次数限制retries 参数控制防止无限重试if (retries > 0) { /* 重试 */ } else { throw error; }建议 2~3 次为宜。