wwf
4 天以前 f56e474c81bb25845b46cf99c85bd313dbfcd3b5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
import axios from 'axios'
import $qxueyou from '@/config/qxueyou.js'
import { getUUID } from "@/utils/tool.js";
 
let createAxios = axios.create({
  baseURL: $qxueyou.serverRoot,
  timeout: 30000,
  headers: {
    "Content-Type": `application/json;charset=utf-8`
  }
})
 
createAxios.all = axios.all
createAxios.spread = axios.spread
 
// Token 工具函数
const ACCESS_TOKEN_KEY = $qxueyou.ACCESS_TOKEN_KEY;
const REFRESH_TOKEN_KEY = $qxueyou.REFRESH_TOKEN_KEY;
export const tokenUtils = {
  // 获取 Access Token
  getAccessToken() {
    return localStorage.getItem(ACCESS_TOKEN_KEY);
  },
  // 获取 Refresh Token
  getRefreshToken() {
    return localStorage.getItem(REFRESH_TOKEN_KEY);
  },
  // 设置 Token
  setTokens(accessToken, refreshToken) {
    if (accessToken) {
      localStorage.setItem(ACCESS_TOKEN_KEY, accessToken);
    }
    if (refreshToken) {
      localStorage.setItem(REFRESH_TOKEN_KEY, refreshToken);
    }
  },
  // 清除 Token
  clearTokens() {
    localStorage.removeItem(ACCESS_TOKEN_KEY);
    localStorage.removeItem(REFRESH_TOKEN_KEY);
  },
  // 检查 Token 是否存在
  hasTokens() {
    return !!(this.getAccessToken() && this.getRefreshToken());
  },
}
let isRefreshing = false;
// 刷新 token 期间的请求队列
let refreshQueue = [];
// 刷新 Access Token
export async function refreshAccessToken() {
  const currentRefreshToken = tokenUtils.getRefreshToken();
  if (!currentRefreshToken) {
    throw new Error("No refresh token available");
  }
  try {
    const response = await createAxios.post(
      `/system/auth/refresh-token?refreshToken=${currentRefreshToken}`
    );
 
    if (response.data && response.data.code === 0) {
      const { accessToken, refreshToken: newRefreshToken } = response.data.data;
      tokenUtils.setTokens(accessToken, newRefreshToken);
      return accessToken;
    } else {
      throw new Error("Token refresh failed");
    }
  } catch (error) {
    console.error('Token refresh error:', error);
    throw error;
  }
}
 
let strTrim = function(data) {
  let newData = {...data}
  Object.keys(newData).forEach((key) => {
    if (typeof newData[key] === 'string') {
      newData[key] = newData[key].trim()
    }
  })
  return newData
}
 
//网络请求监听
createAxios.interceptors.request.use(
  function(config) {
    // 刷新 token 的请求不需要添加 Authorization header
    if (!config.url.includes('/auth/refresh-token')) {
      config.headers = {
        ...config.headers,
        Authorization: localStorage.getItem('accessToken')
      }
    }
    config.flag = getUUID().toString().slice(-4)
    if (config.data) {
      console.log(`data-${config.flag} `, config.data)
      // config.data = JSON.stringify(config.data)
    }
    if (config.params) {
      console.log(`params-${config.flag} `, config.params)
      // config.params = strTrim(config.params)
    }
    return config
  },
  function(error) {
    return Promise.reject(error)
  }
)
 
createAxios.interceptors.response.use(
  async response => {
    const resultCode = response.data.code;
    const originalRequest = response.config;
    if (response.data && [500, 400].includes(resultCode)) {
      console.log(response)
      return response
    }
    if (response.data && resultCode == '401') {
      if (!originalRequest._retry && tokenUtils.getRefreshToken) {
        originalRequest._retry = true;
 
        if (isRefreshing) {
          // 如果正在刷新,将请求加入队列
          return new Promise((resolve, reject) => {
            refreshQueue.push({ resolve, reject, config: originalRequest });
          });
        }
 
        isRefreshing = true;
 
        try {
          const newAccessToken = await refreshAccessToken();
 
          // 处理队列中的请求
          refreshQueue.forEach(({ resolve, config }) => {
            config.headers.Authorization = newAccessToken;
            resolve(createAxios(config));
          });
          refreshQueue = [];
 
          // 重新发送原始请求
          originalRequest.headers.Authorization = newAccessToken;
          return createAxios(originalRequest)
        } catch (refreshError) {
          console.log(refreshError)
          // 刷新失败,处理队列中的请求
          refreshQueue.forEach(({ reject }) => {
            reject(refreshError);
          });
          refreshQueue = [];
          tokenUtils.clearTokens();
          // $store.commit("session/loginFlag", false);
          // $store.commit("session/userInfo", {});
          // 可以在这里触发登录页面跳转
        } finally {
          isRefreshing = false;
        }
      } else {
        tokenUtils.clearTokens();
        // $store.commit("session/loginFlag", false);
        // $store.commit("session/userInfo", {});
      }
    }
 
    console.log(`url-${response.config.flag} `, response.config.url, response.data)
    return response
  },
  error => {
    // store.commit('network/changeNetworkState', false)
    if (!error.response) return Promise.reject(error)
 
    // store.commit('network/status', error.response.status)
    if (401 === error.response.status) {
      // 刷新 token 的请求返回 401 时,直接返回错误,不要抛出新的错误
      if (error.config && error.config.url && error.config.url.includes('/auth/refresh-token')) {
        return Promise.reject(error)
      }
      // store.commit('session/clearUser')
      // store.commit('endea/clearShareK')
      // store.commit('network/logout')
      throw new Error('登录失效')
    }
    return Promise.reject(error)
  }
)
 
export default createAxios