request.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import config from '@/config.js'; // 引入配置文件
  2. import store from '@/store'
  3. let apiBaseUrl = '';
  4. // console.log(process.env.NODE_ENV)
  5. if (process.env.NODE_ENV === 'development') {//本地开发环境
  6. const SYSTEM_INFO = uni.getSystemInfoSync();//获取系统信息的同步接口
  7. apiBaseUrl = SYSTEM_INFO.uniPlatform === 'web' ? config.proxyBaseUrl:config.apiBaseUrl;//读取配置文件的apiBaseUrl变量
  8. } else {//生产/测试环境
  9. apiBaseUrl = config.apiBaseUrl
  10. }
  11. console.log(process.env.NODE_ENV,apiBaseUrl)
  12. // 防止 401 重复处理的标志
  13. let isHandling401 = false;
  14. const request = (options) => {
  15. if(options.url.endsWith('.js')) return;
  16. // console.log("进入requset",options);
  17. return new Promise((resolve, reject) => {
  18. // console.log("进入Promise",options);
  19. let contentType = 'application/json';//默认请求头content-type
  20. // 根据请求方法和请求数据类型设置请求头content-type 以下方法在安卓里报错
  21. // if (options.method === 'POST' && options.data instanceof FormData)
  22. // {
  23. // // FormData 请求头content-type
  24. // contentType = 'multipart/form-data';
  25. // } else if (options.method === 'POST' && typeof options.data === 'string')
  26. // {
  27. // // 字符串请求头content-type
  28. // contentType = 'application/x-www-form-urlencoded';
  29. // }
  30. // console.log("准备请求");
  31. uni.request({
  32. url: apiBaseUrl + options.url,
  33. method: options.method || 'GET',
  34. data: options.data || {},
  35. header: {
  36. 'content-type': contentType,
  37. ...(options.header || {})
  38. },
  39. success: (res) => {
  40. if (res.statusCode === 200) {
  41. resolve(res);
  42. } else {
  43. reject(res);
  44. }
  45. },
  46. fail: (err) => {
  47. reject(err);
  48. }
  49. });
  50. });
  51. };
  52. // 请求拦截器
  53. const requestInterceptor = (config) => {
  54. // 在发送请求之前做些什么
  55. const token = uni.getStorageSync('token'); // 假设从本地存储获取token
  56. // 确保 options.header 存在
  57. if (!config.header) {
  58. config.header = {};
  59. }
  60. if (token) {
  61. config.header.Authorization = `${token}`; // 添加token请求头
  62. }
  63. return config;
  64. };
  65. const isLoginPage = () => {
  66. const pages = getCurrentPages();
  67. if (pages.length === 0) return false;
  68. const currentPage = pages[pages.length - 1];
  69. return currentPage.route === 'pages/login/index';
  70. };
  71. const clearUserInfoAndRedirect = () => {
  72. // 清除用户信息
  73. uni.removeStorageSync('token');
  74. uni.removeStorageSync('userInfo');
  75. uni.removeStorageSync('schoolsList');
  76. // 清除store中的信息
  77. store.commit('userStore/SET_TOKEN', '');
  78. store.commit('userStore/SET_USER_INFO', {});
  79. store.commit('userStore/SET_SCHOOLSLIST', '');
  80. // 跳转到登录页
  81. if (!isLoginPage()) {
  82. uni.reLaunch({
  83. url: '/pages/login/index'
  84. });
  85. }
  86. };
  87. const responseInterceptor = (response) => {
  88. if (response.data.code === 401) {
  89. // 如果已经在处理 401,直接抛出错误,防止重复调用 sign_out
  90. if (isHandling401) {
  91. throw new Error(response.data.message || response.data.msg || '未授权,请重新登录');
  92. }
  93. isHandling401 = true;
  94. // 清除用户信息并跳转到登录页
  95. clearUserInfoAndRedirect();
  96. // 延迟重置标志位,避免连续请求都触发401
  97. setTimeout(() => {
  98. isHandling401 = false;
  99. }, 2000);
  100. throw new Error(response.data.message || response.data.msg || '未授权,请重新登录');
  101. }
  102. if (response.data.code === 500 || response.data.code === 503) {
  103. uni.showToast({
  104. title: response.data.message || response.data.msg || '服务器繁忙,请稍后重试',
  105. icon: 'none',
  106. duration: 3000
  107. });
  108. throw new Error(response.data.message || response.data.msg || '服务器内部错误');
  109. }
  110. if (response.data.code === 200 || response.data.code === 400 || response.data.code === 601 || response.data.code === 602) {
  111. return response.data;
  112. }
  113. if (response.data.code === 403) {
  114. throw new Error(response.data.message || response.data.msg || '禁止访问');
  115. }
  116. if (response.data.code === 404) {
  117. throw new Error(response.data.message || response.data.msg || '资源未找到');
  118. }
  119. throw new Error(`未知错误,状态码: ${response.statusCode}`);
  120. };
  121. const requestWithInterceptors = (options) => {
  122. // console.log("进来了",options);
  123. const config = requestInterceptor(options);
  124. // console.log("进来了",config);
  125. return request(config).then(responseInterceptor);
  126. };
  127. // 封装常用的请求方法
  128. const get = (url, data, header) => {
  129. return requestWithInterceptors({ url, data, header, method: 'GET' });
  130. };
  131. const post = (url, data, header) => {
  132. return requestWithInterceptors({ url, data, header, method: 'POST' });
  133. };
  134. const put = (url, data, header) => {
  135. return requestWithInterceptors({ url, data, header, method: 'PUT' });
  136. };
  137. const del = (url, data, header) => {
  138. return requestWithInterceptors({ url, data, header, method: 'DELETE' });
  139. };
  140. export default {
  141. request,
  142. get,
  143. post,
  144. put,
  145. del
  146. };