1、修改index.ts

src/index.ts添加headers为空对象,去掉拦截器代码:
image.png

2、修改Axios.ts

修改src/axios/Axios.ts,添加默认配置:
image.png

image.png

image.png

完整代码:

  1. // src/axios/Axios.ts
  2. import { AxiosRequestConfig, AxiosResponse } from "./types";
  3. import AxiosInterceptorManager, {
  4. Interceptor,
  5. } from "./AxiosInterceptorManager";
  6. import qs from "qs";
  7. import parseHeaders from "parse-headers";
  8. const defaults: AxiosRequestConfig = {
  9. method: "get",
  10. timeout: 0,
  11. headers: {
  12. common: {
  13. accept: "application/json",
  14. },
  15. },
  16. };
  17. const getStyleMethods = ["get", "head", "delete", "options"]; // get风格请求
  18. const postStyleMethods = ["post", "put", "patch"]; // post风格请求
  19. getStyleMethods.forEach((method: string) => {
  20. defaults.headers![method] = {};
  21. });
  22. postStyleMethods.forEach((method: string) => {
  23. defaults.headers![method] = {
  24. "content-type": "application/json", // 请求体格式
  25. };
  26. });
  27. const allMethods = [...getStyleMethods, ...postStyleMethods];
  28. export default class Axios<T> {
  29. public default: AxiosRequestConfig = defaults;
  30. public interceptors = {
  31. request: new AxiosInterceptorManager<AxiosRequestConfig>(),
  32. response: new AxiosInterceptorManager<AxiosResponse<T>>(),
  33. };
  34. // T用来限制相应对象response里的data的类型
  35. request(
  36. config: AxiosRequestConfig
  37. ): Promise<AxiosResponse<T> | AxiosRequestConfig> {
  38. // 默认的header和定义的head合并
  39. config.headers = Object.assign(this.default.headers, config.headers);
  40. const chain: Array<
  41. Interceptor<AxiosRequestConfig> | Interceptor<AxiosResponse<T>>
  42. > = [
  43. {
  44. // 请求
  45. onFulfilled: this.dispatchRequest,
  46. // onRejected可以省略
  47. onRejected: (error: any) => error,
  48. },
  49. ];
  50. // 请求拦截器倒序
  51. this.interceptors.request.interceptors.forEach(
  52. (interceptor: Interceptor<AxiosRequestConfig> | null) => {
  53. interceptor && chain.unshift(interceptor);
  54. }
  55. );
  56. // 响应拦截器正序
  57. this.interceptors.response.interceptors.forEach(
  58. (interceptor: Interceptor<AxiosResponse<T>> | null) => {
  59. interceptor && chain.push(interceptor);
  60. }
  61. );
  62. let promise: any = Promise.resolve(config);
  63. while (chain.length) {
  64. const { onFulfilled, onRejected } = chain.shift()!;
  65. promise = promise.then(onFulfilled, onRejected);
  66. }
  67. return promise;
  68. }
  69. // 定义一个开发请求的方法
  70. dispatchRequest<T>(
  71. config: AxiosRequestConfig
  72. ): Promise<AxiosResponse<T> | AxiosRequestConfig> {
  73. return new Promise<AxiosResponse<T>>(function (resolve, reject) {
  74. let { method, url, params, headers, data, timeout } = config;
  75. let request = new XMLHttpRequest();
  76. // {name:'admin',password:'123'}转成?name=admin&password=123
  77. if ((params && method === "get") || method === "GET") {
  78. params = qs.stringify(params);
  79. // 判断url有无参数
  80. url += (url!.indexOf("?") === -1 ? "?" : "&") + params;
  81. }
  82. request.open(method!, url!, true);
  83. // 返回json类型
  84. request.responseType = "json";
  85. request.onreadystatechange = function () {
  86. if (request.readyState === 4 && request.status !== 0) {
  87. if (request.status >= 200 && request.status < 300) {
  88. let response: AxiosResponse<T> = {
  89. data: request.response ? request.response : request.responseText,
  90. status: request.status,
  91. statusText: request.statusText,
  92. headers: parseHeaders(request.getAllResponseHeaders()),
  93. config,
  94. request,
  95. };
  96. resolve(response);
  97. } else {
  98. // 错误状态码处理
  99. reject(`error:request failed with status code ${request.status}`);
  100. }
  101. }
  102. };
  103. // 处理header
  104. /**
  105. * headers:{
  106. * common:{accept:'application/json'}
  107. * post:{'content-type':'application/json'}
  108. * }
  109. */
  110. debugger
  111. if (headers) {
  112. for (let key in headers) {
  113. // common表示所有方法都生效或者key是一个方法名
  114. if (key === "common" || allMethods.includes(key)) {
  115. if (key === "common" || key === config.method) {
  116. for (let key2 in headers[key]) {
  117. request.setRequestHeader(key2, headers[key][key2]);
  118. }
  119. }
  120. } else {
  121. request.setRequestHeader(key, headers[key]);
  122. }
  123. }
  124. }
  125. // 处理data
  126. let body: string | null = null;
  127. if (data) {
  128. body = JSON.stringify(data);
  129. }
  130. // 网络错误处理
  131. request.onerror = function () {
  132. reject("net:error");
  133. };
  134. // 超时设置错误
  135. if (timeout) {
  136. request.timeout = timeout;
  137. request.ontimeout = function () {
  138. reject(`err:timeout of ${timeout}ms exceeded`);
  139. };
  140. }
  141. request.send(body);
  142. });
  143. }
  144. }

3、源代码

代码地址:https://gitee.com/linhexs/handwritten-axios/tree/4.merge-config/