service.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import Request from "@/common/luch-request/index.js";
  2. import { ACCESS_TOKEN } from "@/common/util/constants.js";
  3. import configService from "./config.service.js";
  4. import tip from "@/common/util/tip.js";
  5. import store from "@/store/index.js";
  6. const getTokenStorage = () => {
  7. let token = "";
  8. try {
  9. token = uni.getStorageSync(ACCESS_TOKEN);
  10. } catch (e) {
  11. //TODO handle the exception
  12. console.log("getTokenStorage", token);
  13. }
  14. return token;
  15. };
  16. const http = new Request();
  17. // 记录上次因登录失效跳登录页的时间,用于防止连续跳转
  18. let lastReloginAt = 0;
  19. http.setConfig((config) => {
  20. /* 设置全局配置 */
  21. config.baseUrl = configService.apiUrl; /* 根域名不同 */
  22. config.header = {
  23. ...config.header,
  24. };
  25. return config;
  26. });
  27. /**
  28. * 自定义验证器,如果返回true 则进入响应拦截器的响应成功函数(resolve),否则进入响应拦截器的响应错误函数(reject)
  29. * @param { Number } statusCode - 请求响应体statusCode(只读)
  30. * @return { Boolean } 如果为true,则 resolve, 否则 reject
  31. */
  32. // 有默认,非必写
  33. http.validateStatus = (statusCode) => {
  34. return statusCode === 200;
  35. };
  36. http.interceptor.request((config, cancel) => {
  37. /* 请求之前拦截器 */
  38. console.log(config, "config---");
  39. config.baseUrl = configService.apiUrl || uni.getStorageSync("apiUrl") || "";
  40. config.header = {
  41. ...config.header,
  42. "X-Access-Token": getTokenStorage(),
  43. };
  44. /*
  45. if (!token) { // 如果token不存在,调用cancel 会取消本次请求,但是该函数的catch() 仍会执行
  46. cancel('token 不存在') // 接收一个参数,会传给catch((err) => {}) err.errMsg === 'token 不存在'
  47. }
  48. */
  49. return config;
  50. });
  51. // 必须使用异步函数,注意
  52. var that = this;
  53. http.interceptor.response(
  54. async (response) => {
  55. /* 请求之后拦截器 */
  56. // if (response.data.code !== 200) { // 服务端返回的状态码不等于200,则reject()
  57. // return Promise.reject(response)
  58. // }
  59. return response;
  60. },
  61. (response) => {
  62. // 请求错误做点什么
  63. console.log("请求错误做点什么", response);
  64. if (response) {
  65. let data = response.data;
  66. const token = uni.getStorageSync(ACCESS_TOKEN);
  67. console.log("------异常响应------", token);
  68. console.log("------异常响应------", data.code);
  69. switch (data.code) {
  70. case 403:
  71. tip.error("拒绝访问");
  72. break;
  73. case 500:
  74. // 仅在服务端明确提示 Token 失效时才清理登录态;
  75. // 服务端偶发 500(如冷启动时网关未就绪)不应清掉本地登录信息,
  76. // 否则重新打开应用会莫名要求重新登录
  77. if (data.message == "Token失效,请重新登录") {
  78. tip.alert("登录已过期");
  79. store.dispatch("Logout").then(() => {
  80. uni.reLaunch({ url: "/pages/login/login" });
  81. });
  82. }
  83. break;
  84. case 404:
  85. break;
  86. case 504:
  87. break;
  88. case 401:
  89. {
  90. console.log("------异常响应-401-----", 401);
  91. const pages = getCurrentPages() || [];
  92. const currentPage = pages[pages.length - 1];
  93. const currentRoute = currentPage ? currentPage.route : "";
  94. // 已经在登录页,不再重复跳转
  95. if (currentRoute === "pages/login/login") {
  96. return;
  97. }
  98. // 多个请求同时 401 时只跳一次,避免连续跳转被拦截
  99. const now = Date.now();
  100. if (lastReloginAt && now - lastReloginAt < 3000) {
  101. return;
  102. }
  103. lastReloginAt = now;
  104. // 登录失效:清空页面栈进入登录页,否则登录页侧滑会回到系统内部页面
  105. uni.reLaunch({
  106. url: "/pages/login/login",
  107. });
  108. return;
  109. }
  110. if (token) {
  111. /* store.dispatch('Logout').then(() => {
  112. setTimeout(() => {
  113. window.location.reload()
  114. }, 1500)
  115. }) */
  116. }
  117. break;
  118. default:
  119. tip.error({
  120. duration: 0,
  121. forbidClick: true,
  122. message: data.message,
  123. });
  124. break;
  125. }
  126. }
  127. return response;
  128. },
  129. );
  130. export { http };