1、修改index.ts文件
添加请求拦截器响应拦截器代码:
// src/index.ts
axios.interceptors.request.use(
(config: AxiosRequestConfig): AxiosRequestConfig => {
console.log("请求拦截器1");
return config;
}
);
axios.interceptors.response.use((response: AxiosResponse) => {
if (response.status === 200) {
console.log("响应拦截器1")
response.data.message += "1";
}
return response;
});
2、修改types.ts文件
添加interceptors对象类型:
// src/axios/types
export interface AxiosInstance {
<T = any>(config: AxiosRequestConfig): Promise<AxiosResponse<T>>;
interceptors:{
request: AxiosInterceptorManager<AxiosRequestConfig>;
response: AxiosInterceptorManager<AxiosResponse>;
}
}
3、添加AxiosInterceptorManager.ts文件
// src/axios/AxiosInterceptorManager.ts
interface OnFulfilled<V> {
(value: V): V | Promise<V>;
}
interface OnRejected {
(error: any): any;
}
// 某一个拦截器
export interface Interceptor<V> {
// 成功回调
onFulfilled?: OnFulfilled<V>;
// 失败的回调
onRejected?: OnRejected;
}
// V可能是AxiosRequestConfig,也可能是AxiosResponse
export default class AxiosInterceptorManager<V> {
public interceptors: Array<Interceptor<V> | null> = [];
// 返回值为索引
use(onFulfilled?: OnFulfilled<V>, onRejected?: OnRejected): number {
this.interceptors.push({
onFulfilled,
onRejected,
});
return this.interceptors.length - 1;
}
eject(id:number) {
if(this.interceptors[id]){
this.interceptors[id] = null
}
}
}
4、修改Axios.ts文件
添加拦截器,修改request方法:
// src/axios/Axios.ts
import { AxiosRequestConfig, AxiosResponse } from "./types";
import AxiosInterceptorManager, {
Interceptor,
} from "./AxiosInterceptorManager";
import qs from "qs";
import parseHeaders from "parse-headers";
export default class Axios<T> {
public interceptors = {
request: new AxiosInterceptorManager<AxiosRequestConfig>(),
response: new AxiosInterceptorManager<AxiosResponse<T>>(),
};
// T用来限制相应对象response里的data的类型
request(config: AxiosRequestConfig): Promise<AxiosResponse<T> | AxiosRequestConfig> {
const chain: Array<
Interceptor<AxiosRequestConfig> | Interceptor<AxiosResponse<T>>
> = [
{
// 请求
onFulfilled: this.dispatchRequest,
// onRejected可以省略
onRejected: (error: any) => error,
},
];
// 请求拦截器倒序
this.interceptors.request.interceptors.forEach(
(interceptor: Interceptor<AxiosRequestConfig> | null) => {
interceptor && chain.unshift(interceptor);
}
);
// 响应拦截器正序
this.interceptors.response.interceptors.forEach(
(interceptor: Interceptor<AxiosResponse<T>> | null) => {
interceptor && chain.push(interceptor);
}
);
let promise: any = Promise.resolve(config);
while (chain.length) {
const { onFulfilled, onRejected } = chain.shift()!;
promise = promise.then(onFulfilled, onRejected);
}
return promise
}
// 定义一个开发请求的方法
dispatchRequest<T>(config: AxiosRequestConfig): Promise<AxiosResponse<T> | AxiosRequestConfig> {
return new Promise<AxiosResponse<T>>(function (resolve, reject) {
let { method, url, params, headers, data, timeout } = config;
let request = new XMLHttpRequest();
// {name:'admin',password:'123'}转成?name=admin&password=123
if ((params && method === "get") || method === "GET") {
params = qs.stringify(params);
// 判断url有无参数
url += (url!.indexOf("?") === -1 ? "?" : "&") + params;
}
request.open(method!, url!, true);
// 返回json类型
request.responseType = "json";
request.onreadystatechange = function () {
if (request.readyState === 4 && request.status !== 0) {
if (request.status >= 200 && request.status < 300) {
let response: AxiosResponse<T> = {
data: request.response ? request.response : request.responseText,
status: request.status,
statusText: request.statusText,
headers: parseHeaders(request.getAllResponseHeaders()),
config,
request,
};
resolve(response);
} else {
// 错误状态码处理
reject(`error:request failed with status code ${request.status}`);
}
}
};
// 处理header
if (headers) {
for (let key in headers) {
request.setRequestHeader(key, headers[key]);
}
}
// 处理data
let body: string | null = null;
if (data) {
body = JSON.stringify(data);
}
// 网络错误处理
request.onerror = function () {
reject("net:error");
};
// 超时设置错误
if (timeout) {
request.timeout = timeout;
request.ontimeout = function () {
reject(`err:timeout of ${timeout}ms exceeded`);
};
}
request.send(body);
});
}
}
5、实现效果
6、源代码
代码地址:https://gitee.com/linhexs/handwritten-axios/tree/3.interceptors/