Axios 拦截器概述
Axios 拦截器允许你在请求发送前或响应接收后统一处理数据,是实现全局配置、错误处理、权限验证等功能的重要机制。
请求拦截器(Request Interceptors)
基本用法
javascript// 添加请求拦截器 axios.interceptors.request.use( function (config) { // 在发送请求之前做些什么 return config; }, function (error) { // 对请求错误做些什么 return Promise.reject(error); } );
实际应用场景
1. 统一添加认证 Token
javascriptaxios.interceptors.request.use( config => { const token = localStorage.getItem('token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }, error => { return Promise.reject(error); } );
2. 添加时间戳防止缓存
javascriptaxios.interceptors.request.use( config => { if (config.method === 'get') { config.params = { ...config.params, _t: Date.now() }; } return config; } );
3. 显示加载状态
javascriptlet requestCount = 0; axios.interceptors.request.use( config => { requestCount++; if (requestCount === 1) { // 显示全局 loading showLoading(); } return config; } );
响应拦截器(Response Interceptors)
基本用法
javascript// 添加响应拦截器 axios.interceptors.response.use( function (response) { // 对响应数据做点什么 return response; }, function (error) { // 对响应错误做点什么 return Promise.reject(error); } );
实际应用场景
1. 统一错误处理
javascriptaxios.interceptors.response.use( response => response, error => { const { response } = error; if (response) { switch (response.status) { case 401: // 未授权,清除 token 并跳转到登录页 localStorage.removeItem('token'); window.location.href = '/login'; break; case 403: message.error('没有权限访问该资源'); break; case 404: message.error('请求的资源不存在'); break; case 500: message.error('服务器内部错误'); break; default: message.error(response.data.message || '请求失败'); } } else { message.error('网络错误,请检查网络连接'); } return Promise.reject(error); } );
2. 响应数据格式化
javascriptaxios.interceptors.response.use( response => { // 假设后端统一返回格式:{ code: 0, data: {}, message: '' } const res = response.data; if (res.code !== 0) { message.error(res.message); return Promise.reject(new Error(res.message)); } return res.data; // 直接返回 data,简化组件中的调用 } );
3. 隐藏加载状态
javascriptaxios.interceptors.response.use( response => { requestCount--; if (requestCount === 0) { hideLoading(); } return response; }, error => { requestCount--; if (requestCount === 0) { hideLoading(); } return Promise.reject(error); } );
移除拦截器
javascriptconst myInterceptor = axios.interceptors.request.use(() => {}); axios.interceptors.request.eject(myInterceptor);
为实例添加拦截器
javascriptconst instance = axios.create({ baseURL: 'https://api.example.com' }); instance.interceptors.request.use(config => { // 只对当前实例生效 return config; });
多个拦截器的执行顺序
javascriptaxios.interceptors.request.use(config => { console.log('请求拦截器 1'); return config; }); axios.interceptors.request.use(config => { console.log('请求拦截器 2'); return config; }); // 执行顺序:请求拦截器 2 → 请求拦截器 1 → 发送请求 // 响应拦截器执行顺序与添加顺序相反
最佳实践
- 错误处理要完整:请求和响应拦截器都要处理错误情况
- 记得返回 config/response:否则请求不会继续
- 使用实例隔离:不同服务使用不同实例,避免相互影响
- 避免副作用:拦截器中不要修改原始参数对象
- 添加请求标识:方便调试和追踪