axios之interceptorManager.js源码

interceptorManager

interceptorManager.js 是 Axios 中拦截器管理器的核心实现,位于 lib/core/InterceptorManager.js

文件定义了一个 InterceptorManager 类,它采用职责链模式和观察者模式,用于管理请求和响应拦截器,提供了添加、移除和遍历拦截器的方法。

拦截器管理器本身不关心执行顺序,只负责存储和遍历。真正决定顺序逻辑在 /lib/core/Axios.jsrequest 方法中。

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import utils from '../utils.js';

class InterceptorManager {
constructor() {
this.handlers = [];
}

use(fulfilled, rejected, options) {
this.handlers.push({
fulfilled,
rejected,
synchronous: options ? options.synchronous : false,
runWhen: options ? options.runWhen : null,
});
return this.handlers.length - 1;
}

eject(id) {
if (this.handlers[id]) {
this.handlers[id] = null;
}
}

clear() {
if (this.handlers) {
this.handlers = [];
}
}

forEach(fn) {
utils.forEach(this.handlers, function forEachHandler(h) {
if (h !== null) {
fn(h);
}
});
}
}

export default InterceptorManager;

this.handlers

InterceptorManager 类的核心属性是 handlers,它是一个数组,用于存储所有注册的拦截器。每个拦截器按注册顺序存储,执行时也是按此顺序,数组索引作为拦截器的 ID。

每个拦截器对象包含以下属性:

  • fulfilled:成功回调函数,用于处理成功响应。
  • rejected:失败回调函数,用于处理失败响应。
  • synchronous:是否同步执行,默认值为 false
  • runWhen:运行条件,默认值为 null

use(…) {}

源码:

1
2
3
4
5
6
7
8
9
use(fulfilled, rejected, options) {
this.handlers.push({
fulfilled,
rejected,
synchronous: options ? options.synchronous : false,
runWhen: options ? options.runWhen : null,
});
return this.handlers.length - 1;
}

注册拦截器方法,将拦截器对象存入 handlers 数组并返回当前拦截器的索引(即 ID)。这个 ID 可用于后续通过 eject 方法移除该拦截器。

  • fulfilled:Promise 成功时的处理函数(即 then 的回调)
  • rejected:Promise 失败时的处理函数(即 catch 的回调)
  • options:控制拦截器行为
    • synchronous:是否同步执行(默认 false,异步执行)
    • 条件判断函数,返回 false 时跳过该拦截器,可以基于请求配置动态决定是否使用某个拦截器

使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const instance = axios.create();
// 添加请求拦截器
instance.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
}, {

runWhen: function(config) {
// 只在请求方法为 GET 时执行该拦截器
return config.method === 'get';
}
});

// 添加响应拦截器
instance.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});

eject(id) {}

源码:

1
2
3
4
5
eject(id) {
if (this.handlers[id]) {
this.handlers[id] = null;
}
}

移除拦截器方法,根据拦截器 ID 移除对应的拦截器。移除时,会将对应的拦截器移除后,将数组中的空位填充为 null,不是删除数组元素,而是设置为 null,可保持其他拦截器的 ID 不变(如果删除元素,后续 ID 会变化)。

使用示例:

1
2
const myInterceptor = instance.interceptors.request.use(function () {/*...*/});
instance.interceptors.request.eject(myInterceptor);

clear() {}

源码:

1
2
3
4
5
clear() {
if (this.handlers) {
this.handlers = [];
}
}

重置 this.handlers 为空数组,用于重置实例的所有拦截器。

使用示例:

1
instance.interceptors.request.clear();

forEach(fn) {}

源码:

1
2
3
4
5
6
7
forEach(fn) {
utils.forEach(this.handlers, function forEachHandler(h) {
if (h !== null) {
fn(h);
}
});
}

遍历 this.handlers 数组,对每个非 null 的拦截器调用 fn 函数(跳过被 eject 删除的拦截器)。


axios之interceptorManager.js源码
http://example.com/axios/interceptorManager/
作者
傅阳臣
发布于
2026年4月30日
许可协议