1、修改index.ts
src/index.ts添加headers为空对象,去掉拦截器代码:
2、修改Axios.ts
修改src/axios/Axios.ts,添加默认配置:
完整代码:
// src/axios/Axios.ts
import { AxiosRequestConfig, AxiosResponse } from "./types";
import AxiosInterceptorManager, {
Interceptor,
} from "./AxiosInterceptorManager";
import qs from "qs";
import parseHeaders from "parse-headers";
const defaults: AxiosRequestConfig = {
method: "get",
timeout: 0,
headers: {
common: {
accept: "application/json",
},
},
};
const getStyleMethods = ["get", "head", "delete", "options"]; // get风格请求
const postStyleMethods = ["post", "put", "patch"]; // post风格请求
getStyleMethods.forEach((method: string) => {
defaults.headers![method] = {};
});
postStyleMethods.forEach((method: string) => {
defaults.headers![method] = {
"content-type": "application/json", // 请求体格式
};
});
const allMethods = [...getStyleMethods, ...postStyleMethods];
export default class Axios<T> {
public default: AxiosRequestConfig = defaults;
public interceptors = {
request: new AxiosInterceptorManager<AxiosRequestConfig>(),
response: new AxiosInterceptorManager<AxiosResponse<T>>(),
};
// T用来限制相应对象response里的data的类型
request(
config: AxiosRequestConfig
): Promise<AxiosResponse<T> | AxiosRequestConfig> {
// 默认的header和定义的head合并
config.headers = Object.assign(this.default.headers, config.headers);
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
/**
* headers:{
* common:{accept:'application/json'}
* post:{'content-type':'application/json'}
* }
*/
debugger
if (headers) {
for (let key in headers) {
// common表示所有方法都生效或者key是一个方法名
if (key === "common" || allMethods.includes(key)) {
if (key === "common" || key === config.method) {
for (let key2 in headers[key]) {
request.setRequestHeader(key2, headers[key][key2]);
}
}
} else {
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);
});
}
}
3、源代码
代码地址:https://gitee.com/linhexs/handwritten-axios/tree/4.merge-config/