index.ts 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. import Axios, {
  2. AxiosInstance,
  3. AxiosRequestConfig,
  4. CustomParamsSerializer
  5. } from "axios";
  6. import {
  7. PureHttpError,
  8. RequestMethods,
  9. PureHttpResponse,
  10. PureHttpRequestConfig
  11. } from "./types.d";
  12. import { stringify } from "qs";
  13. import NProgress from "../progress";
  14. // import { loadEnv } from "@build/index";
  15. import { getToken } from "@/utils/auth";
  16. import { useUserStoreHook } from "@/store/modules/user";
  17. // 加载环境变量 VITE_PROXY_DOMAIN(开发环境) VITE_PROXY_DOMAIN_REAL(打包后的线上环境)
  18. // const { VITE_PROXY_DOMAIN, VITE_PROXY_DOMAIN_REAL } = loadEnv();
  19. // 相关配置请参考:www.axios-js.com/zh-cn/docs/#axios-request-config-1
  20. const defaultConfig: AxiosRequestConfig = {
  21. // baseURL:
  22. // process.env.NODE_ENV === "production"
  23. // ? VITE_PROXY_DOMAIN_REAL
  24. // : VITE_PROXY_DOMAIN,
  25. // 当前使用mock模拟请求,将baseURL制空,如果你的环境用到了http请求,请删除下面的baseURL启用上面的baseURL,并将第14行、19行代码注释取消
  26. baseURL: "",
  27. timeout: 10000,
  28. headers: {
  29. Accept: "application/json, text/plain, */*",
  30. "Content-Type": "application/json",
  31. "X-Requested-With": "XMLHttpRequest"
  32. },
  33. // 数组格式参数序列化(https://github.com/axios/axios/issues/5142)
  34. paramsSerializer: {
  35. serialize: stringify as unknown as CustomParamsSerializer
  36. }
  37. };
  38. class PureHttp {
  39. constructor() {
  40. this.httpInterceptorsRequest();
  41. this.httpInterceptorsResponse();
  42. }
  43. /** 初始化配置对象 */
  44. private static initConfig: PureHttpRequestConfig = {};
  45. /** 保存当前Axios实例对象 */
  46. private static axiosInstance: AxiosInstance = Axios.create(defaultConfig);
  47. /** 请求拦截 */
  48. private httpInterceptorsRequest(): void {
  49. PureHttp.axiosInstance.interceptors.request.use(
  50. async (config: PureHttpRequestConfig) => {
  51. const $config = config;
  52. // 开启进度条动画
  53. NProgress.start();
  54. // 优先判断post/get等方法是否传入回掉,否则执行初始化设置等回掉
  55. if (typeof config.beforeRequestCallback === "function") {
  56. config.beforeRequestCallback($config);
  57. return $config;
  58. }
  59. if (PureHttp.initConfig.beforeRequestCallback) {
  60. PureHttp.initConfig.beforeRequestCallback($config);
  61. return $config;
  62. }
  63. /** 请求白名单,放置一些不需要token的接口(通过设置请求白名单,防止token过期后再请求造成的死循环问题) */
  64. const whiteList = ["/refreshToken", "/login"];
  65. return whiteList.some(v => config.url.indexOf(v) > -1)
  66. ? config
  67. : new Promise(resolve => {
  68. const data = getToken();
  69. if (data) {
  70. const now = new Date().getTime();
  71. const expired = parseInt(data.expires) - now <= 0;
  72. if (expired) {
  73. // token过期刷新
  74. useUserStoreHook()
  75. .handRefreshToken({ refreshToken: data.refreshToken })
  76. .then(res => {
  77. config.headers["Authorization"] =
  78. "Bearer " + res.data.accessToken;
  79. resolve($config);
  80. });
  81. } else {
  82. config.headers["Authorization"] =
  83. "Bearer " + data.accessToken;
  84. resolve($config);
  85. }
  86. } else {
  87. resolve($config);
  88. }
  89. });
  90. },
  91. error => {
  92. return Promise.reject(error);
  93. }
  94. );
  95. }
  96. /** 响应拦截 */
  97. private httpInterceptorsResponse(): void {
  98. const instance = PureHttp.axiosInstance;
  99. instance.interceptors.response.use(
  100. (response: PureHttpResponse) => {
  101. const $config = response.config;
  102. // 关闭进度条动画
  103. NProgress.done();
  104. // 优先判断post/get等方法是否传入回掉,否则执行初始化设置等回掉
  105. if (typeof $config.beforeResponseCallback === "function") {
  106. $config.beforeResponseCallback(response);
  107. return response.data;
  108. }
  109. if (PureHttp.initConfig.beforeResponseCallback) {
  110. PureHttp.initConfig.beforeResponseCallback(response);
  111. return response.data;
  112. }
  113. return response.data;
  114. },
  115. (error: PureHttpError) => {
  116. const $error = error;
  117. $error.isCancelRequest = Axios.isCancel($error);
  118. // 关闭进度条动画
  119. NProgress.done();
  120. // 所有的响应异常 区分来源为取消请求/非取消请求
  121. return Promise.reject($error);
  122. }
  123. );
  124. }
  125. /** 通用请求工具函数 */
  126. public request<T>(
  127. method: RequestMethods,
  128. url: string,
  129. param?: AxiosRequestConfig,
  130. axiosConfig?: PureHttpRequestConfig
  131. ): Promise<T> {
  132. const config = {
  133. method,
  134. url,
  135. ...param,
  136. ...axiosConfig
  137. } as PureHttpRequestConfig;
  138. // 单独处理自定义请求/响应回掉
  139. return new Promise((resolve, reject) => {
  140. PureHttp.axiosInstance
  141. .request(config)
  142. .then((response: undefined) => {
  143. resolve(response);
  144. })
  145. .catch(error => {
  146. reject(error);
  147. });
  148. });
  149. }
  150. /** 单独抽离的post工具函数 */
  151. public post<T, P>(
  152. url: string,
  153. params?: T,
  154. config?: PureHttpRequestConfig
  155. ): Promise<P> {
  156. return this.request<P>("post", url, params, config);
  157. }
  158. /** 单独抽离的get工具函数 */
  159. public get<T, P>(
  160. url: string,
  161. params?: T,
  162. config?: PureHttpRequestConfig
  163. ): Promise<P> {
  164. return this.request<P>("get", url, params, config);
  165. }
  166. }
  167. export const http = new PureHttp();