网站首页 > 基础教程 正文
Axios 拦截器允许在请求和响应阶段插入处理逻辑。以下是其原理、实现及优雅应用:
拦截器原理
- 队列结构:请求和响应拦截器分别存储在队列中,请求拦截器在发送请求前执行,响应拦截器在接收响应后执行。
- Promise 链:通过构建 Promise 链,依次执行拦截器处理函数。请求拦截器按添加顺序执行,响应拦截器同样按添加顺序执行。
- 错误处理:任一拦截器返回 rejected Promise 会跳过后续拦截器,直接进入错误处理。
手写核心逻辑
class InterceptorManager {
constructor() {
this.handlers = [];
}
use(fulfilled, rejected) {
this.handlers.push({ fulfilled, rejected });
}
}
class Axios {
constructor() {
this.interceptors = {
request: new InterceptorManager(),
response: new InterceptorManager(),
};
}
request(config) {
let chain = [this.dispatchRequest, undefined]; // 初始链
// 请求拦截器按顺序插入到链首
this.interceptors.request.handlers.reverse().forEach(interceptor => {
chain.unshift(interceptor.fulfilled, interceptor.rejected);
});
// 响应拦截器按顺序添加到链尾
this.interceptors.response.handlers.forEach(interceptor => {
chain.push(interceptor.fulfilled, interceptor.rejected);
});
let promise = Promise.resolve(config);
while (chain.length) {
promise = promise.then(chain.shift(), chain.shift());
}
return promise;
}
dispatchRequest(config) {
// 模拟实际请求
return new Promise(resolve => {
setTimeout(() => resolve({ data: config.url, status: 200 }), 100);
});
}
}
// 使用示例
const axios = new Axios();
// 添加请求拦截器
axios.interceptors.request.use(config => {
console.log('请求拦截器1');
config.headers = { Authorization: 'Bearer token' };
return config;
});
axios.interceptors.request.use(config => {
console.log('请求拦截器2');
return config;
});
// 添加响应拦截器
axios.interceptors.response.use(response => {
console.log('响应拦截器1');
return response.data; // 返回处理后的数据
});
axios.interceptors.response.use(response => {
console.log('响应拦截器2');
return response;
});
axios.request({ url: '/api/data' })
.then(data => console.log('成功:', data))
.catch(err => console.error('失败:', err));
拦截器应用场景
- 请求处理:
- 添加认证头:config.headers.Authorization = 'Bearer token'
- 请求数据格式化:转换数据格式或加密
- 响应处理:
- 统一错误处理:检查状态码,处理 401 跳转登录
- 数据解析:提取响应数据,如 return response.data
- 全局Loading:
- 请求前显示 Loading,响应后隐藏
优雅实践建议
- 模块化:将拦截器拆分到独立文件,便于维护。
// auth-interceptor.js
export function requestAuth(config) {
config.headers.Auth = 'xxx';
return config;
}
错误处理:统一在响应拦截器中处理错误。
axios.interceptors.response.use(null, err => {
if (err.response.status === 401) {
redirectToLogin();
}
return Promise.reject(err);
});
- 避免副作用:拦截器应保持纯净,避免修改外部状态。
- 取消拦截器:通过 eject 移除不必要的拦截器。
const interceptor = axios.interceptors.request.use(...);
axios.interceptors.request.eject(interceptor);
执行顺序示例
请求拦截器1 → 请求拦截器2 → 发送请求 → 响应拦截器1 → 响应拦截器2 → 最终结果
通过合理使用拦截器,可提升代码复用性,统一管理请求/响应逻辑,使代码更简洁易维护。
- 上一篇: SQLREST工具的功能概述及使用指南
- 下一篇: TeX是门语言(续三)(tem语言)
猜你喜欢
- 2025-05-08 最全的 Vue 面试题+详解答案(vue的一些面试题)
- 2025-05-08 Array类型简介(array常用的几种方法)
- 2025-05-08 2021最全VUE面试题,奥利给(vue 面试题 2021)
- 2025-05-08 Vue3基础难点总结(vue3技巧)
- 2025-05-08 使用Axios 拦截器解决「 前端并发冲突 」 问题
- 2025-05-08 浅析vue封装自定义插件(vue自己封装组件)
- 2025-05-08 perl基础——数组(perl数组初始化)
- 2025-05-08 如何在控制台打印出一个表格?cli-table3了解一下
- 2025-05-08 ES6史上最全数JS数组方法合集-02-数组操作
- 2025-05-08 3个 Vue $set 的应用场景(vue中的set方法)
- 最近发表
-
- 掌握SpringBoot-2.3的容器探针:实战篇
- kubernetes基础知识之驱逐节点(k8s驱逐节点后恢复)
- Linux环境中制作网络哨兵Sentinel Docker镜像
- k8s之配置CNI网络(k8s 网络配置)
- docker实战之:镜像更新(docker 镜像升级替换)
- 离线在docker镜像方式部署ragflow0.17.2
- Linux日常小技巧Docker打包(docker打包lnmp)
- 使用dockerfile构建docker镜像(docker通过dockerfile构建镜像命令)
- 「云原生」Containerd ctr,crictl 和 nerdctl 命令介绍与实战操作
- Kylin安装Dify(kylin安装部署)
- 标签列表
-
- jsp (69)
- pythonlist (60)
- gitpush (78)
- gitreset (66)
- python字典 (67)
- dockercp (63)
- gitclone命令 (63)
- dockersave (62)
- pythonif (68)
- pythonifelse (59)
- deletesql (62)
- c++模板 (62)
- c#event (59)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- exec命令 (59)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- console.table (62)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)