axios.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import axios, { AxiosRequestConfig, AxiosRequestHeaders } from 'axios';
  2. import { showMessage } from './status'; // 引入状态码文件
  3. import { ElMessage, ElMessageBox } from 'element-plus' // 引入el 提示框,这个项目里用什么组件库这里引什么
  4. import { useAppStore } from '@/stores/index'
  5. import router from '@/router'
  6. // 设置接口超时时间
  7. axios.defaults.timeout = 60000;
  8. console.log(import.meta.env.VITE_API_URL);
  9. // 请求地址,这里是动态赋值的的环境变量,下一篇会细讲,这里跳过
  10. // @ts-ignore
  11. axios.defaults.baseURL = import.meta.env.VITE_API_URL//import.meta.env.VITE_API_URL; http://192.168.8.103:9999 https://apidoc.raycos.net
  12. // 请求拦截器
  13. axios.interceptors.request.use(function (config) {
  14. const store = useAppStore();
  15. config.headers['Content-Type'] = 'application/json;charset=UTF-8';
  16. // 统一设置用户身份 token
  17. if (store.user && store.user.token) {
  18. (config.headers as AxiosRequestHeaders).Authorization = `Bearer ${store.user.token}`
  19. }
  20. return config
  21. }, function (error) {
  22. return Promise.reject(error)
  23. })
  24. // 控制登录过期的锁(是否正在处理登录过期)
  25. let isRefreshing = false
  26. let isShowingError = false;
  27. // 响应拦截器
  28. axios.interceptors.response.use(function (response) {
  29. // 统一处理接口响应错误,如 token 过期无效、服务端异常等
  30. const status = response.data.status
  31. const store = useAppStore();
  32. /* 正确响应 */
  33. if (!status || status === 200) {
  34. return response
  35. }
  36. /* 错误响应 */
  37. // 登录过期处理
  38. if (status === 401) {
  39. if (isRefreshing) return Promise.reject(response)
  40. isRefreshing = true
  41. ElMessageBox.confirm('登录已过期,您可以取消停留在此页面,或确认重新登录', '登录过期', {
  42. confirmButtonText: '确认',
  43. cancelButtonText: '取消'
  44. })
  45. .then(() => {
  46. // 清除本地登录状态
  47. store.setUser(null)
  48. // 跳转到登录页
  49. router.push({
  50. name: 'login',
  51. query: {
  52. redirect: router.currentRoute.value.fullPath
  53. }
  54. })
  55. })
  56. .catch(() => { })
  57. .finally(() => {
  58. isRefreshing = false
  59. })
  60. // 抛出异常
  61. return Promise.reject(response)
  62. }
  63. // 其他错误响应
  64. return response;
  65. }, function (error) {
  66. const { response } = error;
  67. if (response) {
  68. // 请求已发出,但是不在2xx的范围
  69. showMessage(response.code); // 传入响应码,匹配响应码对应信息
  70. ElMessage.error(response.data.message || '请求失败,请稍后重试');
  71. return Promise.reject(response.data);
  72. } else {
  73. // 处理网络错误或请求未发出的情况
  74. // 处理网络错误或请求未发出的情况
  75. if (!isShowingError) {
  76. isShowingError = true;
  77. //ElMessage.error('网络连接异常,请稍后再试!');
  78. setTimeout(() => {
  79. isShowingError = false; // 重置标志位
  80. }, 3000); // 3秒后允许再次显示错误
  81. }
  82. return Promise.reject(error);
  83. }
  84. })
  85. // 封装 GET POST 请求并导出
  86. export function request(url = '', params = {}, type = 'POST') {
  87. //设置 url params type 的默认值
  88. return new Promise((resolve, reject) => {
  89. let promise
  90. // 根据请求类型设置请求方法
  91. switch (type.toUpperCase()) {
  92. case 'GET':
  93. promise = axios({
  94. url,
  95. params,
  96. method: 'GET'
  97. });
  98. break;
  99. case 'POST':
  100. promise = axios({
  101. url,
  102. data: params,
  103. method: 'POST'
  104. });
  105. break;
  106. case 'PUT':
  107. promise = axios({
  108. url,
  109. data: params,
  110. method: 'PUT'
  111. });
  112. break;
  113. default:
  114. promise = axios({
  115. url,
  116. data: params,
  117. method: 'POST' // 默认为POST
  118. });
  119. }
  120. //处理返回
  121. promise.then(res => {
  122. resolve(res)
  123. }).catch(err => {
  124. reject(err)
  125. })
  126. })
  127. }