request.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
  2. import { Session } from '/@/utils/storage';
  3. import { useMessageBox } from '/@/hooks/message';
  4. import qs from 'qs';
  5. import other from './other';
  6. /**
  7. * 创建并配置一个 Axios 实例对象
  8. */
  9. const service: AxiosInstance = axios.create({
  10. baseURL: import.meta.env.VITE_API_URL,
  11. timeout: 50000, // 全局超时时间
  12. paramsSerializer: {
  13. serialize: (params: any) => {
  14. return qs.stringify(params, {arrayFormat: 'repeat'});
  15. }
  16. }
  17. });
  18. /**
  19. * Axios请求拦截器,对请求进行处理
  20. * 1. 序列化get请求参数
  21. * 2. 统一增加Authorization和TENANT-ID请求头
  22. * 3. 自动适配单体、微服务架构不同的URL
  23. * @param config AxiosRequestConfig对象,包含请求配置信息
  24. */
  25. service.interceptors.request.use(
  26. (config: AxiosRequestConfig) => {
  27. // 统一增加Authorization请求头, skipToken 跳过增加token
  28. const token = Session.getToken();
  29. if (token && !config.headers?.skipToken) {
  30. config.headers![CommonHeaderEnum.AUTHORIZATION] = `Bearer ${token}`;
  31. }
  32. // 请求报文加密
  33. if (config.headers![CommonHeaderEnum.ENC_FLAG]) {
  34. const enc = other.encryption(JSON.stringify(config.data), import.meta.env.VITE_PWD_ENC_KEY);
  35. config.data = {
  36. encryption: enc,
  37. };
  38. }
  39. // 自动适配单体和微服务架构不同的URL
  40. config.url = other.adaptationUrl(config.url);
  41. // 处理完毕,返回config对象
  42. return config;
  43. },
  44. (error) => {
  45. // 对请求错误进行处理
  46. return Promise.reject(error);
  47. }
  48. );
  49. /**
  50. * 响应拦截器处理函数
  51. * @param response 响应结果
  52. * @returns 如果响应成功,则返回响应的data属性;否则,抛出错误或者执行其他操作
  53. */
  54. const handleResponse = (response: AxiosResponse<any>) => {
  55. if (response.data.code === 1) {
  56. throw response.data;
  57. }
  58. // 针对密文返回解密
  59. if (response.data.encryption) {
  60. const originData = JSON.parse(other.decryption(response.data.encryption, import.meta.env.VITE_PWD_ENC_KEY));
  61. response.data = originData;
  62. return response.data;
  63. }
  64. return response.data;
  65. };
  66. /**
  67. * 添加 Axios 的响应拦截器,用于全局响应结果处理
  68. */
  69. service.interceptors.response.use(handleResponse, (error) => {
  70. const status = Number(error.response.status) || 200;
  71. if (status === 424) {
  72. useMessageBox()
  73. .confirm('令牌状态已过期,请点击重新登录')
  74. .then(() => {
  75. Session.clear(); // 清除浏览器全部临时缓存
  76. window.location.href = '/'; // 去登录页
  77. return;
  78. });
  79. }
  80. return Promise.reject(error.response.data);
  81. });
  82. // 常用header
  83. export enum CommonHeaderEnum {
  84. 'TENANT_ID' = 'TENANT-ID',
  85. 'ENC_FLAG' = 'Enc-Flag',
  86. 'AUTHORIZATION' = 'Authorization',
  87. }
  88. // 导出 axios 实例
  89. export default service;