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(); // 添加唯一请求 ID
return 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 仍是大多数场景下的首选。