request.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. import axios from 'axios'
  2. import Vue from "vue";
  3. import {Message, MessageBox} from "element-ui";
  4. import store from "@/store";
  5. import {removeToken} from "@/utils/auth";
  6. import router, {resetRouter} from "@/router";
  7. import {doEncrypt, doDecryptStr,doSign,doVerifySignature,userinfoEncrypt,userinfoDecrypt} from '@/utils/smutil'
  8. const service = axios.create({
  9. headers: {'Cache-Control': 'no-cache'},
  10. baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  11. // withCredentials: true, // send cookies when cross-domain requests
  12. timeout: 1000 * 60 * 10 // request timeout
  13. })
  14. service.interceptors.request.use(
  15. config => {
  16. const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
  17. // get请求映射params参数
  18. if (config.method === 'get' && config.params) {
  19. if (config.params.toString().indexOf('secretData') !=-1 && config.params.toString().indexOf('paramSign')){
  20. // 不是token刷新后执行上次操作,进行参数加密。
  21. let encryptParam = doEncrypt(JSON.stringify(config.params))
  22. // 参数签名
  23. let paramSign = doSign(JSON.stringify(config.params))
  24. let result = 'secretData=' + encryptParam + '&paramSign=' + paramSign
  25. config.params = result
  26. }
  27. }
  28. if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put' || config.method === 'delete')) {
  29. if (config.url != '/getMailCode') {
  30. if (config.data !== undefined) {
  31. // 参数加密
  32. let encryptParam = doEncrypt(JSON.stringify(config.data))
  33. // 参数签名
  34. let paramSign = doSign(JSON.stringify(config.data))
  35. const param = {
  36. secretData: encryptParam,
  37. paramSign: paramSign
  38. }
  39. config.data = param
  40. if (config.url!='/user/login'){
  41. config.headers.post['Content-Type'] = 'application/json';
  42. }
  43. }
  44. else{
  45. Message({
  46. message: '请求拦截器检测出config.data是undefined不能提交!',
  47. type: 'error',
  48. duration: 5 * 1000
  49. })
  50. return
  51. }
  52. }
  53. }
  54. if (sessionStorage.getItem("jy")!=="undefined" && sessionStorage.getItem("jy")!==undefined && sessionStorage.getItem("jy")!=null) { // 判断是否存在token,如果存在的话,则每个http header都加上token
  55. let tokenStr = sessionStorage.getItem("jy")
  56. config.headers['Authorization'] = tokenStr.split("&")[0]
  57. config.headers['JySign'] = tokenStr.split("&")[1]
  58. // console.log('Authorization='+tokenStr)
  59. // console.log('TokenSign='+config.headers['TokenSign'])
  60. }
  61. return config
  62. },
  63. error => {
  64. // do something with request error
  65. // console.log(error) // for debug
  66. return Promise.reject(error)
  67. }
  68. )
  69. // 是否正在刷新的标记
  70. let isRefreshing = false
  71. //重试队列
  72. let requests = []
  73. // response interceptor
  74. service.interceptors.response.use(
  75. /**
  76. * Determine the request status by custom code
  77. * Here is just an example
  78. * You can also judge the status by HTTP Status Code
  79. */
  80. response => {
  81. const res = response.data
  82. let returnStr = res.split("&")
  83. let returnData = returnStr[0].split("=")[1]
  84. let returnSign = returnStr[1].split("=")[1]
  85. // 解密
  86. let decData = doDecryptStr(returnData)
  87. // 验签
  88. let verifyResult = doVerifySignature(decData, returnSign)
  89. if (!verifyResult) {
  90. return Promise.reject(new Error('返回数据验签失败' || 'Error'))
  91. }
  92. let data = JSON.parse(decData)
  93. // if the custom code is not 20000, it is judged as an error.
  94. //console.log(res.code)
  95. if (data.code > 1) {
  96. // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
  97. if (data.code === 50008 || data.code === 50012 || data.code === 50014) {
  98. // to re-login
  99. MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
  100. confirmButtonText: 'Re-Login',
  101. cancelButtonText: 'Cancel',
  102. type: 'warning'
  103. }).then(() => {
  104. store.dispatch('user/resetToken').then(() => {
  105. location.reload()
  106. })
  107. })
  108. }
  109. return Promise.reject(new Error(data.data))
  110. } else {
  111. return data
  112. }
  113. },
  114. async error => {
  115. if (error.response) {
  116. switch (error.response.status) {
  117. case 400:
  118. Message({
  119. message: '系统异常,请联系管理员!',
  120. type: 'error',
  121. duration: 5 * 1000
  122. })
  123. break
  124. case 401:
  125. console.log('用户验证失败!')
  126. // 返回 401 清除token信息并跳转到登录页面
  127. removeToken()
  128. resetRouter()
  129. Message({
  130. message: error.response.data,
  131. type: 'error',
  132. duration: 5 * 1000
  133. })
  134. break
  135. case 402:
  136. console.log('权限不足!')
  137. // 返回 401 清除token信息并跳转到登录页面
  138. removeToken()
  139. resetRouter()
  140. Message({
  141. message: error.response.data,
  142. type: 'error',
  143. duration: 5 * 1000
  144. })
  145. break
  146. case 403:
  147. console.log('登录超时!')
  148. // 返回 401 清除token信息并跳转到登录页面
  149. removeToken()
  150. resetRouter()
  151. router.push('/login')
  152. Message({
  153. message: error.response.data,
  154. type: 'error',
  155. duration: 5 * 1000
  156. })
  157. break
  158. case 410:
  159. removeToken()
  160. router.push('/404')
  161. Message({
  162. message: error.response.data,
  163. type: 'error',
  164. duration: 5 * 1000
  165. })
  166. break
  167. case 409:
  168. if (!isRefreshing) {
  169. isRefreshing = true
  170. //调用刷新token的接口
  171. return await Vue.prototype.$axios.post(
  172. '/refreshToken',{}
  173. ).then((res) => {
  174. // const { token } = res.data
  175. // 替换token
  176. let tokenStr = doEncrypt(res.data)
  177. let sign = doSign(res.data)
  178. sessionStorage.setItem('jy', tokenStr+'&'+sign)
  179. // Vue.prototype.$axios(error.response.config)
  180. // 重新请求接口 前过期的接口
  181. error.config.headers.Authorization = res.data;
  182. requests.length > 0 && requests.map((cb) => {
  183. cb();
  184. });
  185. requests = []; //注意要清空
  186. return Vue.prototype.$axios.request(error.config);
  187. // return error.response.config
  188. }).catch(err => {
  189. console.log(err)
  190. //跳到登录页
  191. removeToken()
  192. router.push('/login')
  193. // return Promise.reject(err)
  194. }).finally(() => {
  195. isRefreshing = false
  196. })
  197. }
  198. else {
  199. // 正在刷新token ,把后来的接口缓冲起来
  200. return new Promise((resolve) => {
  201. requests.push(() => {
  202. error.config.headers.Authorization = sessionStorage.getItem('jy');
  203. resolve(Vue.prototype.$axios.request(error.config));
  204. });
  205. })
  206. }
  207. break
  208. case 500:
  209. Message({
  210. message: '服务器关闭了!请联系相关工作人员',
  211. type: 'error',
  212. duration: 5 * 1000
  213. })
  214. removeToken()
  215. resetRouter()
  216. router.push('/login')
  217. break
  218. case 504:
  219. console.log('服务器关闭了!')
  220. removeToken()
  221. resetRouter()
  222. break
  223. // return Promise.reject(error.response.data)
  224. }
  225. }
  226. else{
  227. return Promise.reject(error)
  228. }
  229. }
  230. )
  231. export default service