vue-axios-optimize 1.0.6 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +167 -195
  2. package/index.js +1 -1
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -28,159 +28,146 @@ api目录大致如下
28
28
  > > >
29
29
  > > > axios-optimize.js
30
30
 
31
- axios-optimize.js文件内容大致如下
31
+ **无配置无感知刷新token时** axios-optimize.js文件内容大致如下
32
32
 
33
33
  ```js
34
- import axios from 'axios'
35
- import instance from '@/api/axios.js'
34
+ import axios from "axios"
35
+ import instance from "@/api/axios"
36
+ import axiosOptimize from "vue-axios-optimize"
37
+ import store from "@/store"
36
38
 
37
- import axiosOptimize from 'vue-axios-optimize'
38
- import { useAppStoreHook } from '@/store/modules/app'
39
- const useAppStore = useAppStoreHook()
39
+ const AxiosOptimize = new axiosOptimize(axios, instance, {
40
+ responseTypesStr: "arraybuffer,blob", // 当axios请求设置 responseType为arraybuffer或blob时,直接返回原始数据
41
+ showLoadingFun: (config, requestingNum) => { // 当需要加载动画的请求数量不为0时的回调函数
42
+ store.commit("app/SET_LOADING_STATUS", true)
43
+ },
44
+ hideLoadingFun: (config, requestingNum) => { // 当需要加载动画的请求数量为0时的回调函数
45
+ store.commit("app/SET_LOADING_STATUS", false)
46
+ },
47
+ responseResultFun: (res) => { // 相应数据格式化
48
+ return res.data // 业务上希望用到的数据
49
+ }
50
+ })
40
51
 
41
- import { useUserStoreHook } from '@/store/modules/user'
52
+ export default AxiosOptimize.instance
53
+ ```
42
54
 
43
- import { ElMessageBox } from 'element-plus'
55
+ **配置无感知刷新token时** axios-optimize.js文件内容大致如下
56
+
57
+ ```js
58
+ import axios from "axios"
59
+ import instance from "@/api/axios"
60
+ import axiosOptimize from "vue-axios-optimize"
61
+ import store from "@/store"
62
+ import {MessageBox} from "element-ui"
44
63
 
45
64
  const AxiosOptimize = new axiosOptimize(axios, instance, {
46
- responseTypesStr: "arraybuffer,blob",
47
- showLoadingFun: () => {
48
- // 展示加载动画方法
49
- useAppStore.setLoadingStatus(true)
65
+ responseTypesStr: "arraybuffer,blob", // 当axios请求设置 responseType为arraybuffer或blob时,直接返回原始数据
66
+ showLoadingFun: (config, requestingNum) => { // 当需要加载动画的请求数量不为0时的回调函数
67
+ store.commit("app/SET_LOADING_STATUS", true)
68
+ },
69
+ hideLoadingFun: (config, requestingNum) => { // 当需要加载动画的请求数量为0时的回调函数
70
+ store.commit("app/SET_LOADING_STATUS", false)
50
71
  },
51
- hideLoadingFun: () => {
52
- // 关闭加载动画方法
53
- useAppStore.setLoadingStatus(false)
72
+ openRefresh: true, // 启用无感知刷新token的开关
73
+ responseResultFun: (res) => { // 相应数据格式化
74
+ return res.data
54
75
  },
55
- openRefresh: true, // 开启无感知刷新token 默认不开 开启时 下面的参数才有效
56
- refreshApiUrl: '/xiaobu-admin/refresh-token', // 刷新tokenApi的 url
57
- getRefreshTokenFun: () => {
58
- const useUserStore = useUserStoreHook()
59
- // 获取refreshToken
60
- return useUserStore.gettersRefreshToken
76
+ refreshApiUrl: "/xiaobuAdmin/refreshToken", // 刷新tokenApi的 url
77
+ getRefreshTokenFun: () => { // 获取refreshToken的方法
78
+ return store.getters.refreshToken
61
79
  },
62
- reloginFun: async (response) => {
63
- // 重新登录方法 建议如下形式清除 缓存中token等信息后 弹框提示 点击确认后 刷新页面
64
- const useUserStore = useUserStoreHook()
65
- // 清除缓存中的token等信息
66
- await useUserStore.clearAuth()
67
- ElMessageBox.alert(`${response.message}`, '提示', {
68
- confirmButtonText: 'OK',
80
+ refreshTokenStore: (refreshToken) => { // 调用刷新token的方法 并将获取到的数据存储到cookie 及axios.js用到token的地方
81
+ return store.dispatch("user/refreshToken", refreshToken)
82
+ },
83
+ reloginFun: async(response) => {
84
+ // 重新登录方法 弹框提示 点击确认后 建议清除 缓存中token等信息后 刷新页面
85
+ MessageBox.alert(`${response.message}`, "提示", {
86
+ confirmButtonText: "OK",
69
87
  showClose: false,
70
- callback: async (action) => {
71
- if (action === 'confirm') {
88
+ callback: async(action) => {
89
+ if (action === "confirm") {
90
+ // 清除缓存中的token等信息
91
+ store.commit("user/CLEAR_AUTH")
72
92
  // 刷新浏览器是为了 跳转登录页时query的redirect 会带上 当前页面地址(路由拦截处的逻辑)
73
93
  window.location.reload()
74
94
  }
75
95
  }
76
96
  })
77
- },
78
- refreshTokenStore: (refreshToken) => {
79
- // 使用refreshToken 调用刷新token接口 获取新的accessToken 并存储到对应缓存中 使接口能用
80
- const useUserStore = useUserStoreHook()
81
- // 调用store的获取refreshToken方法 同时会将新的accessToken存储到缓存
82
- return useUserStore.refreshTokenAction({ refreshToken })
83
- },
84
- setAccessTokenFun: (config, accessToken) => {
85
- // 根据需求给请求头设置 accessToken 如下两种形式可设置请求头 二选一
86
- // Reflect.set(config.headers, 'authorization', 'Bearer ' + accessToken)
87
- config.headers.authorization = 'Bearer ' + accessToken
88
- },
89
- responseResultFun: (res) => {
90
- /*res数据结构大致如下: 为接口返回的最外层数据 加个 请求时的config
91
- {
92
- code: 200,
93
- data: XXX,
94
- message: XXX,
95
- config: {}
96
- }
97
- */
98
- // 此方法配置 返回数据 的 逻辑
99
- if (res.config.responesType === 'blob') {
100
- delete res.config
101
- return res
102
- }
103
- if (res.code === 200) {
104
- return res.data
105
- }
106
- delete res.config
107
- return res
108
- },
109
- formatAccessToken: (data) => {
110
- // 此方法返回 请求接口后 返回的 accessToken
111
- return data.accessToken
112
97
  }
113
98
  })
114
99
 
115
100
  export default AxiosOptimize.instance
116
101
  ```
117
102
 
103
+
104
+
118
105
  axios.js的内容需要做些细微的更改 大致内容如下
119
106
 
120
107
  ```js
121
- import axios from 'axios'
122
- import { ElMessage } from 'element-plus'
123
- import { useUserStoreHook } from '@/store/modules/user'
108
+ import axios from "axios"
109
+ import Message from "@/plugins/reset-message.js"
110
+ import store from "@/store"
124
111
 
125
112
  // 创建axios实例
126
113
  const service = axios.create({
127
- baseURL: '/proxy',
128
- timeout: 10000
114
+ baseURL: window.configObj.baseUrl || process.env.VUE_APP_BASE_URL,
115
+ timeout: window.configObj.timeout || process.env.VUE_APP_TIME_OUT // 请求超时时间
129
116
  })
130
117
 
131
118
  // request拦截器
132
119
  service.interceptors.request.use(
133
- (config) => {
134
- // 一般会请求拦截里面加token
135
- const useUserStore = useUserStoreHook()
136
- const accessToken = useUserStore.gettersAccessToken
120
+ config => {
121
+ const accessToken = store.getters.accessToken
137
122
  if (accessToken) {
138
- config.headers['authorization'] = 'Bearer ' + accessToken
123
+ config.headers.Authorization = "Bearer " + accessToken
139
124
  }
140
125
 
141
126
  return config
142
127
  },
143
- (error) => {
144
- // 这个return 一定记得 带上 否则无法使用
128
+ error => {
145
129
  return Promise.reject(error)
146
130
  }
147
131
  )
148
132
 
149
133
  // respone拦截器
150
134
  service.interceptors.response.use(
151
- async (res) => {
152
- // 二进制数据则直接返回
153
- if (res.request.responseType === "blob" || res.request.responseType === "arraybuffer"){
154
- return res
155
- }
156
- const { config, data } = res
157
-
158
- // code为200 直接返回有用数据 多返回一个config ...data 为接口返回的最外层数据
159
- if (data.code === 200) {
160
- return { ...data, config }
135
+ async response => {
136
+
137
+ const {data, config, status, request} = response
138
+ // 如果自定义代码不是200,则判断为错误。
139
+ if (status !== 200) {
140
+ Message({
141
+ message: data.message || "Error",
142
+ type: "error",
143
+ duration: 5 * 1000
144
+ })
145
+ return { ...data, config, responseErr: true}
146
+ } else {
147
+ // 二进制数据则直接返回
148
+ if (request.responseType === "blob" || request.responseType === "arraybuffer"){
149
+ return response
150
+ }
151
+ if (data.code === 200) {
152
+ return { ...data, config}
153
+ }
154
+ return { ...data, config, responseErr: true}
161
155
  }
162
- // 当项目无 无感知刷新token的功能时 此处对应code该什么逻辑就什么逻辑
163
- // dosomething ... 如 code === 401 时 清除token 刷新页面等
164
-
165
- // 报错时 多返回一个 报错标识 responseErr: true ...data 为接口返回的最外层数据
166
- return { ...data, config, responseErr: true }
167
156
  },
168
- (error) => {
169
- if (error.name === 'AxiosError') {
170
- ElMessage({
171
- showClose: true,
172
- message: `${error.message},请检查网络或联系管理员!`,
173
- type: 'error'
174
- })
157
+ error => {
158
+ if (error.name === "AxiosError") {
159
+ Message.error(error.message)
175
160
  }
176
- // 注意return 不可丢失
177
161
  return Promise.reject(error)
178
162
  }
179
163
  )
180
164
 
181
165
  export default service
166
+
182
167
  ```
183
168
 
169
+
170
+
184
171
  接口处使用,如commo-api.js 大致如下
185
172
 
186
173
  ```js
@@ -222,7 +209,7 @@ export function postDemo1(data = {}, config = {}) {
222
209
  }
223
210
 
224
211
  // post 请求demo 2
225
- export function postDemo2(data = {}, config: UserAxiosRequestConfig = {}) {
212
+ export function postDemo2(data = {}, config = {}) {
226
213
  return axiosOptimize({
227
214
  url: '/xiaobu-admin/postDemo2',
228
215
  method: 'post',
@@ -311,109 +298,88 @@ export function patchDemo2(data = {}, config = {}) {
311
298
 
312
299
  ## options配置
313
300
 
314
- | 参数 | 类型 | 说明 | 是否必传 | 默认值 |
315
- | ------------------------------------------ | -------- | ------------------------------------------------------------ | ------------------------- | ----------------------------------- |
316
- | showLoadingFun(config, requestingNum) | Function | 展示动画,config为该请求的config,requestingNum为目前正在请求几个接口,此处可执行一些展示全局动画的操作 | 否 | 无 |
317
- | hideLoadingFun(config, requestingNum) | Function | 隐藏动画,config为该请求的config,requestingNum为目前正在请求几个接口,此时应该为0,此处可执行关闭全局动画的操作 | 否 | 无 |
318
- | openRefresh | Boolean | 是否开启无感知刷新token | 否 | false |
319
- | refreshApiUrl | String | 请求刷新token接口的api地址 如/xiaobu-admin/refresh-token | 当openRefresh为true时必传 | 无 |
320
- | getRefreshTokenFun() | Function | 获取当前项目的 refreshToken方法, 记得 return 回去 | 当openRefresh为true时必传 | 无 |
321
- | reloginFun(response) | Function | response 为axios实例中返回的数据,此处建议执行清除token相关缓存并弹框提示,点击确认进行刷新页面操作 | 当openRefresh为true时必传 | 无 |
322
- | refreshTokenStore(refreshToken) | Function | refreshToken为当前浏览器缓存的refreshToken,需要返回一个Promise,利用此refreshToken调用接口获取新的accessToken 并设置。v1.0.6及以上 需 resolve(accessToken) 旧版本则resolve(data) data为接口返回的数据 | 当openRefresh为true时必传 | 无 |
323
- | setAccessTokenFun(config, accessToken) | Function | config为该请求的config,accessToken 为新获取的accessToken, 此处需要将accessToken设置到请求头中 | 当openRefresh为true时必传 | 无 |
324
- | responseResultFun(res) | Function | res为axios实例返回的res,格式化接口请求成功后返回的数据 | 非必传 | axios实例返回的res |
325
- | formatAccessTokenFun(data) v1.0.6已废除 | Function | data为responseResultFun报错时返回的res | 非必传 | axios实例返回的res.data.accessToken |
326
- | accessTokenExpirationCode | number | 配置accessToken过期返回的业务状态码 | 非必传 | 401 |
327
- | refreshTokenExpirationCode | number | 配置refreshToken过期返回的业务状态码 | 非必传 | 403 |
328
- | responseTypesStr(v1.0.2) | String | 配置数据返回类型,实现当此类型时返回原封不动的响应数据的data数据 | 非必传 | 无 |
329
-
330
- ## store/user.ts代码大致如下
301
+ | 参数 | 类型 | 说明 | 是否必传 | 默认值 |
302
+ | -------------------------------------------------------- | -------- | ------------------------------------------------------------ | ------------------------- | ----------------------------------- |
303
+ | showLoadingFun(config, requestingNum) | Function | 展示动画,config为该请求的config,requestingNum为目前正在请求几个接口,此处可执行一些展示全局动画的操作 | 否 | 无 |
304
+ | hideLoadingFun(config, requestingNum) | Function | 隐藏动画,config为该请求的config,requestingNum为目前正在请求几个接口,此时应该为0,此处可执行关闭全局动画的操作 | 否 | 无 |
305
+ | openRefresh | Boolean | 是否开启无感知刷新token | 否 | false |
306
+ | refreshApiUrl | String | 请求刷新token接口的api地址 如/xiaobu-admin/refresh-token | 当openRefresh为true时必传 | 无 |
307
+ | getRefreshTokenFun() | Function | 获取当前项目的 refreshToken方法, 记得 return 回去 | 当openRefresh为true时必传 | 无 |
308
+ | reloginFun(response) | Function | response 为axios实例中返回的数据,此处建议执行清除token相关缓存并弹框提示,点击确认进行刷新页面操作 | 当openRefresh为true时必传 | 无 |
309
+ | refreshTokenStore(refreshToken) | Function | refreshToken为当前浏览器缓存的refreshToken,需要返回一个Promise,利用此refreshToken调用接口获取新的accessToken 并设置。v1.0.6及以上无需返回任何数据 | 当openRefresh为true时必传 | 无 |
310
+ | setAccessTokenFun(config, accessToken) (v1.0.8已废除) | Function | config为该请求的config,accessToken 为新获取的accessToken, 此处需要将accessToken设置到请求头中 | 当openRefresh为true时必传 | 无 |
311
+ | responseResultFun(res) | Function | res为axios实例返回的res,格式化接口请求成功后返回的数据 | 非必传 | axios实例返回的res |
312
+ | formatAccessTokenFun(data) v1.0.6已废除 | Function | data为responseResultFun报错时返回的res | 非必传 | axios实例返回的res.data.accessToken |
313
+ | accessTokenExpirationCode | number | 配置accessToken过期返回的业务状态码 | 非必传 | 401 |
314
+ | refreshTokenExpirationCode | number | 配置refreshToken过期返回的业务状态码 | 非必传 | 403 |
315
+ | responseTypesStr(v1.0.2) | String | 配置数据返回类型,实现当此类型时返回原封不动的响应数据的data数据 | 非必传 | 无 |
316
+
317
+ ## store/modules/user.js代码大致如下
331
318
 
332
319
  ```ts
333
- import { defineStore } from 'pinia'
334
- import { store } from '@/store'
335
- import { commonApi } from '@/api'
336
- import storage, { userKey } from '@/utils/storage'
337
- import { setCookie, getCookie, removeCookie, accessTokenKey, refreshTokenKey } from '@/utils/cookie'
338
- import { LoginVO, UserInfoVO, RefreshTokenVO } from '@/api/vo/common-vo'
339
- import { RefreshTokenDTO } from '@/api/dto/common-dto'
340
- const storageData = storage.info()
341
-
342
- const useUserStore = defineStore('user', {
343
- state: () => {
344
- return {
345
- accessToken: getCookie(accessTokenKey) || '',
346
- refreshToken: getCookie(refreshTokenKey) || '',
347
- userInfo: storageData[userKey] || null
348
- }
349
- },
320
+ import { setCookie, getCookie, removeCookie, accessTokenKey, refreshTokenKey } from "@/utils/cookie"
321
+ import { commonApi } from "@/api"
350
322
 
351
- getters: {
352
- gettersRefreshToken: (state) => {
353
- return state.refreshToken
354
- },
355
- gettersAccessToken: (state) => {
356
- return state.accessToken
357
- },
358
- gettersUserInfo: (state) => {
359
- return () => state.userInfo
360
- }
323
+ const getDefaultState = () => {
324
+ return {
325
+ accessToken: getCookie(accessTokenKey) || "", // 认证token
326
+ refreshToken: getCookie(refreshTokenKey) || "", // 刷新token
327
+ }
328
+ }
329
+ const state = getDefaultState()
330
+
331
+ const mutations = {
332
+ // 重置初始化值
333
+ RESET_STATE: (state) => {
334
+ Object.assign(state, getDefaultState())
335
+ },
336
+ // 设置token
337
+ SET_TOKEN: (state, data) => {
338
+ const { accessToken, refreshToken, expiresIn} = data
339
+ state.accessToken = accessToken
340
+ setCookie(accessTokenKey, accessToken, expiresIn)
341
+ state.refreshToken = refreshToken
342
+ setCookie(refreshTokenKey, refreshToken, expiresIn)
361
343
  },
362
344
 
363
- actions: {
364
- // 设置cookie
365
- setToken(data: LoginVO) {
366
- this.accessToken = data.accessToken
367
- setCookie(accessTokenKey, data.accessToken, data.expiresIn)
368
- this.refreshToken = data.refreshToken
369
- setCookie(refreshTokenKey, data.refreshToken, data.expiresIn)
370
- },
371
- // 清除AccessToken及RefreshToken
372
- clearAuth() {
373
- this.accessToken = ''
374
- removeCookie(accessTokenKey)
375
- this.refreshToken = ''
376
- removeCookie(refreshTokenKey)
377
- this.userInfo = null
378
- storage.remove(userKey)
379
- },
380
- // 刷新token
381
- async refreshTokenAction(params: RefreshTokenDTO) {
382
- return new Promise<RefreshTokenVO>((resolve, reject) => {
383
- commonApi
384
- .refreshToken(params)
385
- .then((data) => {
386
- this.setToken(data)
387
- resolve(data)
388
- })
389
- .catch((err) => {
390
- reject(err)
391
- })
392
- })
393
- },
394
-
395
- // 获取用户信息
396
- async getUserInfo() {
397
- return new Promise<UserInfoVO>((resolve, reject) => {
398
- commonApi
399
- .getUserInfo()
400
- .then((data) => {
401
- this.userInfo = data
402
- storage.set(userKey, data)
403
- resolve(data)
404
- })
405
- .catch((err) => {
406
- reject(err)
407
- })
408
- })
409
- }
345
+ // 清除token 及其他可能影响操作的缓存数据
346
+ CLEAR_AUTH: (state) => {
347
+ state.accessToken = ""
348
+ removeCookie(accessTokenKey)
349
+ state.refreshToken = ""
350
+ removeCookie(refreshTokenKey)
351
+ // ...
410
352
  }
411
- })
353
+ }
412
354
 
413
- export function useUserStoreHook() {
414
- return useUserStore(store)
355
+ const actions = {
356
+ // 设置项目token
357
+ setToken({commit}, data) {
358
+ return new Promise((resolve, reject) => {
359
+ commit("SET_TOKEN", data)
360
+ resolve()
361
+ })
362
+ },
363
+ // 刷新token
364
+ refreshToken({commit}, refreshToken) {
365
+ return new Promise((resolve, reject) => {
366
+ commonApi.refreshToken({refreshToken}).then(data => {
367
+ commit("SET_TOKEN", data)
368
+ resolve()
369
+ })
370
+ })
371
+ },
372
+ }
373
+
374
+ export default {
375
+ namespaced: true,
376
+ state,
377
+ mutations,
378
+ actions
415
379
  }
416
380
 
381
+
382
+
417
383
  ```
418
384
 
419
385
  ## 注意
@@ -471,6 +437,12 @@ module.exports = {
471
437
  [vue2-water-marker水印插件](https://www.npmjs.com/package/vue2-water-marker)
472
438
 
473
439
  ## 更新日志
440
+
441
+ ### 1.0.8
442
+
443
+ 1. 【优化】废除options的setAccessTokenFun配置项
444
+ 2. 【优化】将返回数据的config去除
445
+
474
446
  ### 1.0.6
475
447
 
476
448
  1. 【优化】废除options的formatAccessTokenFun配置项
package/index.js CHANGED
@@ -1 +1 @@
1
- class e{instance;requestObj={};requestingNum=0;authErrorArr=[];queue=[];isRefresh=!1;isShowReLoginDialog=!1;constructor(e,s,r){this.instance=s,this.instance.interceptors.request.use((s=>{s?.noShowLoading||(this.requestingNum++,r.showLoadingFun&&r.showLoadingFun(s,this.requestingNum));const i=s.url;if(r.openRefresh){-1===this.authErrorArr.indexOf(i)&&this.isRefresh&&i!==r.refreshApiUrl&&this.authErrorArr.push(i)}if(i&&s.preventDuplicateRequestsType)if("cancel"===s.preventDuplicateRequestsType){this.requestObj[i]&&this.requestObj[i].cancel({config:s,isCancel:!0});const r=e.CancelToken;this.requestObj[i]=r.source(),s.cancelToken=this.requestObj[i].token}else if("prevent"===s.preventDuplicateRequestsType){if("requesting"===this.requestObj[i])return Promise.reject({config:s,isPrevent:!0});this.requestObj[i]="requesting"}return s}),(e=>Promise.reject(e))),this.instance.interceptors.response.use((async e=>{const{config:s,responseErr:i}=e;if(s?.noShowLoading||(this.requestingNum--,this.requestingNum<=0&&(this.requestObj={},r.hideLoadingFun&&r.hideLoadingFun(s,this.requestingNum))),s&&this.requestObj[s.url]&&delete this.requestObj[s.url],i){if(r.openRefresh){const i=this.authErrorArr.indexOf(s.url);if(-1!==i)return this.authErrorArr.splice(i,1),new Promise((e=>{this.queue.push((i=>{r.setAccessTokenFun(s,i),e(this.instance.request(s))}))}));const t=r.accessTokenExpirationCode||401;if(Number(e.code)===t){const i=r.getRefreshTokenFun();if(!i){if(this.isShowReLoginDialog)return;return this.isShowReLoginDialog=!0,r.reloginFun(e),Promise.reject(new Error(e.message||"Error"))}if(this.isRefresh)return new Promise((e=>{this.queue.push((i=>{r.setAccessTokenFun(s,i),e(this.instance.request(s))}))}));this.isRefresh=!0;try{const e=await r.refreshTokenStore(i);return this.queue.forEach((s=>s(e))),this.instance.request(s)}catch{if(this.isShowReLoginDialog)return;return this.isShowReLoginDialog=!0,r.reloginFun(e),Promise.reject(new Error(e.message||"Error"))}finally{this.queue=[],this.isRefresh=!1}}const n=r.refreshTokenExpirationCode||403;if(Number(e.code)===n){if(this.isShowReLoginDialog)return;return this.isShowReLoginDialog=!0,r.reloginFun(e),Promise.reject(new Error(e.message||"Error"))}}return Promise.reject(new Error(e.message||"Error"))}if(r?.responseTypesStr?.toLocaleLowerCase().split(",").includes(s?.responseType?.toLocaleLowerCase()))return e.data;const t=JSON.parse(JSON.stringify(e));return delete t.responseErr,r.responseResultFun?r.responseResultFun(t):t}),(e=>{const s=e.config||e?.message?.config||{};return s?.noShowLoading||(this.requestingNum--,this.requestingNum<=0&&(this.requestObj={},r.hideLoadingFun&&r.hideLoadingFun(s,this.requestingNum))),e.isPrevent||e?.message?.isCancel||delete this.requestObj[s.url],Promise.reject(e)}))}}export default e;
1
+ class e{instance;requestObj={};requestingNum=0;authErrorArr=[];queue=[];isRefresh=!1;isShowReLoginDialog=!1;constructor(e,r,s){this.instance=r,this.instance.interceptors.request.use((r=>{r?.noShowLoading||(this.requestingNum++,s.showLoadingFun&&s.showLoadingFun(r,this.requestingNum));const i=r.url;if(s.openRefresh){-1===this.authErrorArr.indexOf(i)&&this.isRefresh&&i!==s.refreshApiUrl&&this.authErrorArr.push(i)}if(i&&r.preventDuplicateRequestsType)if("cancel"===r.preventDuplicateRequestsType){this.requestObj[i]&&this.requestObj[i].cancel({config:r,isCancel:!0});const s=e.CancelToken;this.requestObj[i]=s.source(),r.cancelToken=this.requestObj[i].token}else if("prevent"===r.preventDuplicateRequestsType){if("requesting"===this.requestObj[i])return Promise.reject({config:r,isPrevent:!0});this.requestObj[i]="requesting"}return r}),(e=>Promise.reject(e))),this.instance.interceptors.response.use((async e=>{const{config:r,responseErr:i}=e;if(r?.noShowLoading||(this.requestingNum--,this.requestingNum<=0&&(this.requestObj={},s.hideLoadingFun&&s.hideLoadingFun(r,this.requestingNum))),r&&this.requestObj[r.url]&&delete this.requestObj[r.url],i){if(s.openRefresh){const i=this.authErrorArr.indexOf(r.url);if(-1!==i)return this.authErrorArr.splice(i,1),new Promise((e=>{this.queue.push((()=>{e(this.instance.request(r))}))}));const t=s.accessTokenExpirationCode||401;if(Number(e.code)===t){const i=s.getRefreshTokenFun();if(!i){if(this.isShowReLoginDialog)return;return this.isShowReLoginDialog=!0,s.reloginFun(e),Promise.reject(new Error(e.message||"Error"))}if(this.isRefresh)return new Promise((e=>{this.queue.push((()=>{e(this.instance.request(r))}))}));this.isRefresh=!0;try{return await s.refreshTokenStore(i),this.queue.forEach((e=>e())),this.instance.request(r)}catch{if(this.isShowReLoginDialog)return;return this.isShowReLoginDialog=!0,s.reloginFun(e),Promise.reject(new Error(e.message||"Error"))}finally{this.queue=[],this.isRefresh=!1}}const n=s.refreshTokenExpirationCode||403;if(Number(e.code)===n){if(this.isShowReLoginDialog)return;return this.isShowReLoginDialog=!0,s.reloginFun(e),Promise.reject(new Error(e.message||"Error"))}}return Promise.reject(new Error(e.message||"Error"))}if(s?.responseTypesStr?.toLocaleLowerCase().split(",").includes(r?.responseType?.toLocaleLowerCase()))return e.data;const t=JSON.parse(JSON.stringify(e));return delete t.responseErr,delete t.config,s.responseResultFun?s.responseResultFun(t):t}),(e=>{const r=e.config||e?.message?.config||{};return r?.noShowLoading||(this.requestingNum--,this.requestingNum<=0&&(this.requestObj={},s.hideLoadingFun&&s.hideLoadingFun(r,this.requestingNum))),e.isPrevent||e?.message?.isCancel||delete this.requestObj[r.url],Promise.reject(e)}))}}export default e;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue-axios-optimize",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "vue项目对axios请求的优化,实现可配置展示全局加载动画,可配置是否重复请求时取消前面的请求或者阻止后面的请求。",
5
5
  "main": "index.js",
6
6
  "scripts": {