1、修改index.ts文件
添加请求拦截器响应拦截器代码:
// src/index.tsaxios.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/typesexport interface AxiosInstance {<T = any>(config: AxiosRequestConfig): Promise<AxiosResponse<T>>;interceptors:{request: AxiosInterceptorManager<AxiosRequestConfig>;response: AxiosInterceptorManager<AxiosResponse>;}}
3、添加AxiosInterceptorManager.ts文件

// src/axios/AxiosInterceptorManager.tsinterface OnFulfilled<V> {(value: V): V | Promise<V>;}interface OnRejected {(error: any): any;}// 某一个拦截器export interface Interceptor<V> {// 成功回调onFulfilled?: OnFulfilled<V>;// 失败的回调onRejected?: OnRejected;}// V可能是AxiosRequestConfig,也可能是AxiosResponseexport 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.tsimport { 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=123if ((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}`);}}};// 处理headerif (headers) {for (let key in headers) {request.setRequestHeader(key, headers[key]);}}// 处理datalet 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/
