Axios 拦截器是 Axios 库中非常强大的功能,它允许你在请求发送前或响应返回后对数据进行处理。下面详细介绍 Axios 拦截器的使用方法:
1. 请求拦截器
基本用法
javascript
import axios from 'axios';
// 添加请求拦截器
axios.interceptors.request.use(
function (config) {
// 在发送请求之前做些什么
console.log('请求配置:', config);
return config;
},
function (error) {
// 对请求错误做些什么
return Promise.reject(error);
}
);
实际应用场景
javascript
// 添加认证 token
axios.interceptors.request.use(
(config) => {
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
// 添加公共参数
axios.interceptors.request.use(
(config) => {
config.params = {
...config.params,
timestamp: Date.now(),
version: '1.0.0'
};
return config;
}
);
2. 响应拦截器
基本用法
javascript
// 添加响应拦截器
axios.interceptors.response.use(
function (response) {
// 2xx 范围内的状态码都会触发该函数
// 对响应数据做点什么
console.log('响应数据:', response);
return response;
},
function (error) {
// 超出 2xx 范围的状态码都会触发该函数
// 对响应错误做点什么
console.log('响应错误:', error);
return Promise.reject(error);
}
);
实际应用场景
javascript
// 统一处理响应数据
axios.interceptors.response.use(
(response) => {
// 如果后端返回的数据有统一格式,可以在这里处理
const { data, code, message } = response.data;
if (code === 200) {
return data;
} else {
// 业务错误
return Promise.reject(new Error(message));
}
},
(error) => {
// 处理 HTTP 错误
if (error.response) {
switch (error.response.status) {
case 401:
// 未授权,跳转到登录页
window.location.href = '/login';
break;
case 403:
// 禁止访问
console.error('没有权限访问该资源');
break;
case 500:
// 服务器错误
console.error('服务器内部错误');
break;
default:
console.error('请求失败:', error.message);
}
}
return Promise.reject(error);
}
);
3. 完整示例
javascript
import axios from 'axios';
// 创建 axios 实例
const instance = axios.create({
baseURL: 'https://api.example.com',
timeout: 10000,
});
// 请求拦截器
instance.interceptors.request.use(
(config) => {
// 显示 loading
showLoading();
// 添加 token
const token = getToken();
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
// 记录请求开始时间
config.metadata = { startTime: new Date() };
return config;
},
(error) => {
hideLoading();
return Promise.reject(error);
}
);
// 响应拦截器
instance.interceptors.response.use(
(response) => {
// 隐藏 loading
hideLoading();
// 计算请求耗时
const endTime = new Date();
const duration = endTime - response.config.metadata.startTime;
console.log(`请求 ${response.config.url} 耗时: ${duration}ms`);
// 统一处理响应格式
const { code, data, message } = response.data;
if (code === 200) {
return data;
} else {
// 业务逻辑错误
showMessage(message, 'error');
return Promise.reject(new Error(message));
}
},
(error) => {
// 隐藏 loading
hideLoading();
// 处理 HTTP 错误
if (error.response) {
const { status, data } = error.response;
switch (status) {
case 401:
removeToken();
router.push('/login');
break;
case 403:
showMessage('没有权限访问该资源', 'error');
break;
case 500:
showMessage('服务器内部错误', 'error');
break;
default:
showMessage(data?.message || '请求失败', 'error');
}
} else if (error.request) {
// 请求发送失败
showMessage('网络连接失败,请检查网络', 'error');
} else {
// 其他错误
showMessage(error.message, 'error');
}
return Promise.reject(error);
}
);
// 辅助函数
function showLoading() {
// 显示 loading 的逻辑
}
function hideLoading() {
// 隐藏 loading 的逻辑
}
function showMessage(message, type) {
// 显示消息的逻辑
}
function getToken() {
return localStorage.getItem('token');
}
function removeToken() {
localStorage.removeItem('token');
}
export default instance;
4. 移除拦截器
javascript
// 添加拦截器时会返回一个 ID
const requestInterceptor = axios.interceptors.request.use(config => config);
const responseInterceptor = axios.interceptors.response.use(response => response);
// 移除拦截器
axios.interceptors.request.eject(requestInterceptor);
axios.interceptors.response.eject(responseInterceptor);
5. 多个拦截器的执行顺序
javascript
// 拦截器会按照添加顺序执行
axios.interceptors.request.use(config => {
console.log('第一个请求拦截器');
return config;
});
axios.interceptors.request.use(config => {
console.log('第二个请求拦截器');
return config;
});
axios.interceptors.response.use(response => {
console.log('第一个响应拦截器');
return response;
});
axios.interceptors.response.use(response => {
console.log('第二个响应拦截器');
return response;
});
// 执行顺序:
// 第一个请求拦截器 → 第二个请求拦截器 → 请求发送
// 第一个响应拦截器 ← 第二个响应拦截器 ← 响应返回
6. 在特定实例中使用拦截器
javascript
// 创建不同的 axios 实例用于不同的 API
const authApi = axios.create({
baseURL: 'https://auth.api.com'
});
const dataApi = axios.create({
baseURL: 'https://data.api.com'
});
// 为不同实例添加不同的拦截器
authApi.interceptors.request.use(config => {
// 认证相关的拦截逻辑
return config;
});
dataApi.interceptors.request.use(config => {
// 数据相关的拦截逻辑
return config;
});
Axios 拦截器是一个非常实用的功能,可以帮助你统一处理请求和响应,减少重复代码,提高开发效率。