平安校园
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

api.js 2.8 KiB

3 months ago
3 months ago
2 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
2 months ago
2 months ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import {
  2. options
  3. } from '@/http/config.js';
  4. import Request from '@/utils/luch-request/index.js';
  5. const http = new Request(options);
  6. import store from "@/store"
  7. http.interceptors.request.use((config) => { // 可使用async await 做异步操作
  8. // 假设有token值需要在头部需要携带
  9. let token = uni.getStorageSync('token');
  10. if (token) {
  11. config.header['Authorization'] = 'Bearer ' + token;
  12. const jwt = decryptJWT(token);
  13. const exp = getJWTDate(jwt.exp);
  14. // token 已经过期
  15. if (new Date() >= exp) {
  16. let refreshToken = store.state.refreshToken;
  17. // 携带刷新 token
  18. if (refreshToken) {
  19. config.header["X-" + 'Authorization'] = 'Bearer ' + refreshToken;
  20. }
  21. }
  22. }
  23. // #ifndef H5
  24. let url = config.url
  25. if (process.env.NODE_ENV == 'development' && !url.startsWith("http")) {
  26. config.url = url
  27. }
  28. // #endif
  29. return config
  30. }, config => { // 可使用async await 做异步操作
  31. return Promise.reject(config)
  32. })
  33. http.interceptors.response.use((response) => {
  34. checkAndStoreAuthentication(response)
  35. // 服务端返回的状态码不等于200,则reject()
  36. if (response.data.code && response.data.code !== 200) {
  37. setTimeout(() => {
  38. uni.showToast({
  39. title: response.data.msg,
  40. icon: 'none'
  41. });
  42. })
  43. if (response.data.code == 401) {
  44. const pages = getCurrentPages()
  45. const currentPage = pages[pages.length - 1]
  46. store.dispatch('clearToken')
  47. uni.redirectTo({
  48. url: `/pages/login?redirect=/${currentPage.route}`
  49. })
  50. }
  51. return Promise.reject(response);
  52. }
  53. return response.data;
  54. }, (response) => {
  55. /* 对响应错误做点什么 (statusCode !== 200)*/
  56. setTimeout(() => {
  57. uni.showToast({
  58. title: response.data.msg || response.data.error_description || '网络错误',
  59. icon: 'none'
  60. });
  61. })
  62. return Promise.reject(response)
  63. })
  64. /**
  65. * @description 解密 JWT token 的信息
  66. * @param token jwt token 字符串
  67. * @returns <any>object
  68. */
  69. function decryptJWT(token) {
  70. token = token.replace(/_/g, "/").replace(/-/g, "+");
  71. const json = decodeURIComponent(escape(window.atob(token.split(".")[1])));
  72. return JSON.parse(json);
  73. }
  74. /**
  75. * @description 将 JWT 时间戳转换成 Date,主要针对 `exp`,`iat`,`nbf`
  76. * @param timestamp 时间戳
  77. * @returns Date 对象
  78. */
  79. function getJWTDate(timestamp) {
  80. return new Date(timestamp * 1000);
  81. }
  82. /**
  83. * 检查并存储授权信息
  84. * @param res 响应对象
  85. */
  86. const checkAndStoreAuthentication = (res) => {
  87. // 读取响应报文头 token 信息
  88. let token = res.header['access-token'];
  89. let refreshToken = res.header['x-access-token'];
  90. // 判断是否是无效 token
  91. if (token === "invalid_token") {
  92. store.dispatch('clearToken')
  93. }
  94. // 判断是否存在刷新 token,如果存在则存储在本地
  95. else if (refreshToken && token && token !== "invalid_token") {
  96. store.dispatch('setToken',{token,refreshToken})
  97. }
  98. }
  99. export default http;