interceptor.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. import axios from 'axios';
  2. import type { AxiosRequestConfig, AxiosResponse } from 'axios';
  3. import { Message, Modal } from '@arco-design/web-vue';
  4. import { useUserStore } from '@/store';
  5. import { getToken } from '@/utils/auth';
  6. export interface HttpResponse<T = unknown> {
  7. status: number;
  8. msg: string;
  9. code: number;
  10. data: T;
  11. }
  12. if (import.meta.env.VITE_API_BASE_URL) {
  13. axios.defaults.baseURL = import.meta.env.VITE_API_BASE_URL;
  14. }
  15. let API_SCOPE = 'admin';
  16. if (import.meta.env.VITE_API_BASE_SCOPE) {
  17. API_SCOPE = import.meta.env.VITE_API_BASE_SCOPE;
  18. }
  19. axios.interceptors.request.use(
  20. (config: AxiosRequestConfig) => {
  21. // let each request carry token
  22. // this example using the JWT token
  23. // Authorization is a custom headers key
  24. // please modify it according to the actual situation
  25. const token = getToken();
  26. if (token) {
  27. if (!config.headers) {
  28. config.headers = {
  29. };
  30. }
  31. if (API_SCOPE) {
  32. config.headers.scope = API_SCOPE;
  33. }
  34. config.headers.Authorization = `Bearer ${token}`;
  35. }
  36. return config;
  37. },
  38. (error) => {
  39. // do something
  40. return Promise.reject(error);
  41. }
  42. );
  43. // add response interceptors
  44. axios.interceptors.response.use(
  45. (response: AxiosResponse<HttpResponse>) => {
  46. const res = response.data;
  47. // if the custom code is not 20000, it is judged as an error.
  48. if (res.code !== 200) {
  49. Message.error({
  50. content: res.msg || 'Error',
  51. duration: 5 * 1000,
  52. });
  53. // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
  54. if (
  55. [401].includes(res.code) &&
  56. response.config.url !== '/api/user/info'
  57. ) {
  58. Modal.error({
  59. title: 'Confirm logout',
  60. content:
  61. 'You have been logged out, you can cancel to stay on this page, or log in again',
  62. okText: 'Re-Login',
  63. async onOk() {
  64. const userStore = useUserStore();
  65. await userStore.logout();
  66. window.location.reload();
  67. },
  68. });
  69. }
  70. return Promise.reject(new Error(res.msg || 'Error'));
  71. }
  72. return res;
  73. },
  74. (error) => {
  75. const result = error.response;
  76. if (error.response) {
  77. if (error.response.request.responseType === 'arraybuffer' && error.response.data.toString() === '[object ArrayBuffer]') {
  78. const text = Buffer.from(error.response.data).toString('utf8');
  79. result.data = JSON.parse(text);
  80. }
  81. } else {
  82. Message.error({
  83. content: error.msg || 'Request Error',
  84. duration: 5 * 1000,
  85. });
  86. return Promise.reject(error);
  87. }
  88. if (result.data.code !== 200) {
  89. const url = result.data.config?.url
  90. // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
  91. if (result.data.code === 401 && url !== '/api/user/info') {
  92. Modal.error({
  93. title: 'Confirm logout',
  94. content:
  95. 'You have been logged out, you can cancel to stay on this page, or log in again',
  96. okText: 'Re-Login',
  97. async onOk() {
  98. const userStore = useUserStore();
  99. await userStore.logout();
  100. window.location.reload();
  101. },
  102. });
  103. } else {
  104. Message.error({
  105. content: result.data.msg || 'Error',
  106. duration: 5 * 1000,
  107. });
  108. }
  109. }
  110. if (result && typeof (result.data.code) !== 'undefined') {
  111. const err = new Error(result.data.msg);
  112. Message.error({
  113. content: err.message || 'Request Error',
  114. duration: 5 * 1000,
  115. });
  116. return Promise.reject(err);
  117. }
  118. Message.error({
  119. content: error.msg || 'Request Error',
  120. duration: 5 * 1000,
  121. });
  122. return Promise.reject(error);
  123. }
  124. );