Axios 是一个基于 Promise 的 HTTP 客户端,用于浏览器和 Node.js 环境中进行 HTTP 请求。
一、特点与基本用法
1.特点
- 浏览器兼容性好:能在多种现代浏览器中使用,包括 Chrome、Firefox、Safari 等。
- 支持 Promise API:基于 Promise 实现,使得异步操作更易于处理和管理,可方便地进行链式调用和错误处理。
- 拦截请求和响应:可以在请求发送前和响应接收后进行拦截,对请求和响应进行处理,如添加请求头、验证响应数据等。
- 取消请求:提供了取消请求的功能,可在特定情况下取消未完成的请求,节省资源。
- 自动转换 JSON 数据:能自动将响应数据转换为 JSON 格式,方便处理和使用。
特性 | 说明 |
---|---|
Promise 支持 | 基于 Promise 的异步请求,支持 async/await ,链式调用更直观。 |
拦截器机制 | 全局/实例级请求和响应拦截器,可统一添加 Token、处理错误日志等。 |
自动 JSON 转换 | 自动将请求体序列化为 JSON,响应体反序列化为 JSON(可配置 transformRequest/Response )。 |
取消请求 | 基于 CancelToken (旧版)或 AbortController (新版)取消请求。 |
并发请求 | 通过 axios.all 和 axios.spread 处理多个并发请求。 |
浏览器与 Node.js | 支持浏览器(XHR)和 Node.js(HTTP 模块)环境,通用性强。 |
2.基本用法
在浏览器环境中,首先要引入 Axios 库,然后就可以使用它来发送各种 HTTP 请求。例如,发送一个 GET 请求获取数据:
axios.get('https://example.com/api/data').then(response => console.log(response.data)).catch(error => console.error(error));
发送一个 POST 请求来提交数据:
axios.post('https://example.com/api/create', { name: 'John', age: 30 }).then(response => console.log(response.data)).catch(error => console.error(error));
还可以通过配置选项来定制请求,如设置请求头、超时时间等:
axios({method: 'get',url: 'https://example.com/api/data',headers: { 'Authorization': 'Bearer token' },timeout: 5000
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
二、配置
1.全局配置
可以使用axios.defaults
来设置全局默认配置。例如:
axios.defaults.baseURL = 'https://example.com/api';
axios.defaults.headers.common['Authorization'] = 'Bearer token';
axios.defaults.timeout = 5000;
上述代码设置了全局的基础 URL、请求头中的授权信息以及超时时间。
2.实例配置
创建一个 Axios 实例并进行配置:
const instance = axios.create({baseURL: 'https://another-example.com/api',headers: {'Content - Type': 'application/json'},timeout: 3000
});
这样就创建了一个具有特定配置的 Axios 实例,后续使用该实例发送请求时会应用这些配置。
3.请求配置
在发送请求时也可以直接传入配置参数:
axios.get('https://example.com/api/data', {headers: { 'Custom - Header': 'Value' },params: { id: 123 }
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
这里为单个 GET 请求设置了自定义请求头和查询参数。
4.拦截器配置
可以使用拦截器在请求发送前或响应接收后进行一些处理:
// 请求拦截器
axios.interceptors.request.use(config => {// 在发送请求前做些什么,如添加时间戳config.params = { ...config.params, timestamp: Date.now() };return config;
}, error => {return Promise.reject(error);
});// 响应拦截器
axios.interceptors.response.use(response => {// 对响应数据做些处理,如统一格式化response.data = formatResponseData(response.data);return response;
}, error => {return Promise.reject(error);
});
请求拦截器可以修改请求配置,响应拦截器可以处理响应数据。
三、进阶用法示例
(1)自定义实例与配置
// 创建独立实例(如不同后端服务)
const apiClient = axios.create({baseURL: 'https://api.example.com',timeout: 10000,headers: { 'X-Custom-Header': 'value' }
});// 修改实例默认配置
apiClient.defaults.headers.common['Authorization'] = 'Bearer token';
(2)文件上传与进度监控
const formData = new FormData();
formData.append('file', fileInput.files[0]);axios.post('/upload', formData, {headers: { 'Content-Type': 'multipart/form-data' },onUploadProgress: (progressEvent) => {const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total);console.log(`上传进度: ${percent}%`);}
});
(3)错误统一处理
// 响应拦截器统一处理错误
apiClient.interceptors.response.use((response) => response,(error) => {if (error.response) {// 服务端返回 4xx/5xx 错误console.error(`请求失败:${error.response.status}`, error.response.data);} else if (error.request) {// 请求已发送但无响应(如超时)console.error('请求未收到响应', error.request);} else {// 请求配置错误console.error('请求配置错误', error.message);}return Promise.reject(error);}
);
四、Axios 与其他 HTTP 客户端的对比
1. Axios vs Fetch API
特性 | Axios | Fetch API |
---|---|---|
语法简洁性 | 链式调用,配置简洁。 | 需手动处理响应和错误(.then().catch() )。 |
JSON 处理 | 自动序列化请求体和反序列化响应体。 | 需手动调用 response.json() 。 |
拦截器 | 支持全局和实例级拦截器。 | 需自行封装或使用第三方库。 |
取消请求 | 支持 CancelToken 或 AbortController。 | 需使用 AbortController。 |
浏览器兼容性 | 兼容 IE11+(需 polyfill)。 | 兼容现代浏览器,IE 需 polyfill。 |
请求超时 | 原生支持 timeout 配置。 | 需通过 AbortController + setTimeout 实现。 |
2. Axios vs jQuery.ajax
特性 | Axios | jQuery.ajax |
---|---|---|
依赖项 | 轻量级(无 jQuery 依赖)。 | 依赖 jQuery 库。 |
Promise 支持 | 原生 Promise。 | 基于 Deferred 对象(需适配 Promise)。 |
现代特性 | 支持拦截器、取消请求等。 | 功能较基础,扩展性有限。 |
TypeScript 支持 | 官方提供类型定义。 | 需社区维护的类型定义。 |
3. Axios vs 其他库(如 ky、SuperAgent)
特性 | Axios | ky(现代轻量库) | SuperAgent(老牌库) |
---|---|---|---|
体积 | 约 13KB(压缩后)。 | 约 5KB(压缩后)。 | 约 20KB(压缩后)。 |
Node.js 支持 | 支持。 | 仅浏览器环境(需 ky-universal )。 | 支持。 |
链式调用 | 支持。 | 支持(如 ky.get().json() )。 | 支持(.then() 风格)。 |
社区活跃度 | 高(GitHub 50k+ Stars)。 | 中等(GitHub 8k+ Stars)。 | 下降趋势(维护较少)。 |
五、Axios 实践
1. 统一请求管理
封装请求工具类:
class HttpClient {constructor(baseURL) {this.client = axios.create({ baseURL });this._setupInterceptors();}_setupInterceptors() {this.client.interceptors.request.use(this._handleRequest);this.client.interceptors.response.use(this._handleResponse, this._handleError);}_handleRequest(config) {config.headers['X-Request-Id'] = uuidv4(); // 添加唯一请求 IDreturn config;}_handleResponse(response) {return response.data; // 直接返回数据,省略响应结构}_handleError(error) {// 统一错误处理逻辑throw error;}get(url, config) { return this.client.get(url, config); }post(url, data, config) { return this.client.post(url, data, config); }// 其他方法...
}
2. 结合 TypeScript 使用
interface ApiResponse<T> {code: number;data: T;message: string;
}const fetchUser = async (userId: string): Promise<ApiResponse<User>> => {const response = await axios.get<ApiResponse<User>>(`/users/${userId}`);return response.data;
};
3. 性能优化
- 请求缓存:
const cache = new Map();const fetchWithCache = async (url) => {if (cache.has(url)) return cache.get(url);const response = await axios.get(url);cache.set(url, response.data);return response.data;
};
- 并发请求优化:
// 使用 Promise.all 并行请求
const [user, posts] = await Promise.all([axios.get('/user/1'),axios.get('/posts?userId=1')
]);
六、适用场景与总结
1. 推荐使用 Axios 的场景
- 需要拦截器统一处理日志、鉴权等逻辑。
- 项目需兼容浏览器和 Node.js 环境。
- 期望简化 JSON 数据处理和错误处理。
- 需要取消请求或上传进度监控功能。
2. 不推荐使用 Axios 的场景
- 极简项目(可直接使用 Fetch API)。
- 对包体积敏感且无需高级功能(可考虑 ky)。
3.总结
Axios 凭借其丰富的功能、良好的兼容性和强大的社区支持,成为前端开发中最受欢迎的 HTTP 客户端之一。结合 TypeScript 和合理封装,可显著提升代码可维护性和开发效率。对于现代项目,若无需复杂功能,也可考虑轻量替代品(如 ky
),但 Axios 仍是大多数场景下的首选。