axios.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. import Vue from "vue";
  2. import axios from "axios";
  3. import { loadProgressBar } from "./axiosProgress";
  4. import cachingGet from "./axiosCache";
  5. import { Message, Modal } from "iview";
  6. import router from "../router";
  7. //axios配置 start
  8. const qmInstance = axios.create({});
  9. //请求拦截
  10. /**
  11. * A. token lifecycle
  12. * 1. /login UI => localStorage.removeItem('token') && localStorage.setItem('token')
  13. * 2. non /login UI => axios if(!wk_token) wk_token = window.sessionStorage.getItem("token"), send request
  14. * 3. if axios request fail with 401/403, wk_token = null, redirect to /login removeItem('token')
  15. * 4. logout to /login, before send request, invalidate wk_token
  16. * */
  17. let wk_token, wk_key;
  18. qmInstance.interceptors.request.use(
  19. config => {
  20. // debugger;
  21. if (
  22. config.url.includes("/login") === false ||
  23. config.url.includes("/api/ecs_core/auth/thirdPartyStudentAccess") ===
  24. false
  25. ) {
  26. // if (!wk_token) {
  27. wk_token = window.sessionStorage.getItem("token");
  28. wk_key = window.localStorage.getItem("key");
  29. // }
  30. if (wk_token && config.headers.common["token"] == null) {
  31. config.headers.common["token"] = wk_token;
  32. // Axios.defaults.headers.common["key"] = window.localStorage.getItem("key");
  33. config.headers.common["key"] = wk_key;
  34. }
  35. } else {
  36. wk_token = null;
  37. }
  38. return config;
  39. },
  40. error => {
  41. Message.error({
  42. content: error,
  43. duration: 15,
  44. closable: true,
  45. });
  46. return Promise.resolve(error);
  47. }
  48. );
  49. //响应拦截
  50. qmInstance.interceptors.response.use(
  51. response => {
  52. return response;
  53. },
  54. error => {
  55. if (!error.response) {
  56. // "Network Error" 网络不通,直接返回
  57. if (
  58. window.___lastNetworkError === undefined ||
  59. window.___lastNetworkError < Date.now() - 15 * 1000
  60. ) {
  61. Message.error({
  62. content: "网络连接异常,请检查网络设置。",
  63. duration: 15,
  64. closable: true,
  65. });
  66. window.___lastNetworkError = Date.now();
  67. }
  68. window._hmt.push([
  69. "_trackEvent",
  70. location.pathname,
  71. "网络连接异常,请检查网络设置。",
  72. ]);
  73. return Promise.reject(error);
  74. }
  75. // 这里是返回状态码不为200时候的错误处理
  76. let status = error.response.status;
  77. // 登录失效 跳转登录页面
  78. if (status == 403 || status == 401) {
  79. if (
  80. window.___lastInvalidDate === undefined ||
  81. window.___lastInvalidDate < Date.now() - 300
  82. ) {
  83. Message.error({
  84. content: "登录失效,请重新登录!",
  85. duration: 15,
  86. closable: true,
  87. });
  88. window.___lastInvalidDate = Date.now();
  89. const redirectUrl = sessionStorage.getItem("redirectUrl");
  90. if (redirectUrl) {
  91. Modal.error({
  92. title: "确认退出",
  93. content: "登录失效",
  94. onOk: () => {
  95. window.location = redirectUrl;
  96. },
  97. });
  98. } else {
  99. router.push("/login/" + localStorage.getItem("domain"));
  100. }
  101. }
  102. wk_token = null;
  103. // router.push("/login/" + localStorage.getItem("domain"));
  104. return; // 仅显示登录失效,不显示因登录失效造成的后续错误
  105. } else if (status == 502) {
  106. window._hmt.push([
  107. "_trackEvent",
  108. location.pathname,
  109. "服务器异常(502)!",
  110. error.config.url,
  111. ]);
  112. Message.error({
  113. content: "服务器异常(502)!",
  114. duration: 15,
  115. closable: true,
  116. });
  117. return;
  118. } else if (status == 503) {
  119. window._hmt.push([
  120. "_trackEvent",
  121. location.pathname,
  122. "服务器繁忙(503)!请稍后重试。",
  123. error.config.url,
  124. ]);
  125. Message.error({
  126. content: "服务器繁忙(503)!请稍后重试。",
  127. duration: 15,
  128. closable: true,
  129. });
  130. return;
  131. } else if (status != 200) {
  132. window._hmt.push([
  133. "_trackEvent",
  134. location.pathname,
  135. "status: " + status,
  136. error.config.url,
  137. ]);
  138. if (
  139. wk_token &&
  140. ![401, 403].includes(status) &&
  141. !error.config.url.includes("/api/ecs_core/log/studentClient/")
  142. ) {
  143. setTimeout(() => {
  144. qmInstance.post(
  145. "/api/ecs_core/log/studentClient/" + "debug/S-009001",
  146. error.config.url + " 请求失败",
  147. {
  148. headers: {
  149. "Content-Type": "text/plain",
  150. },
  151. }
  152. );
  153. }, 3 * 1000);
  154. }
  155. const data = error.response.data;
  156. if (data && data.desc) {
  157. Message.error({
  158. content: data.desc,
  159. duration: 15,
  160. closable: true,
  161. });
  162. } else {
  163. Message.error({
  164. content: "未定义异常: " + JSON.stringify(data, 2),
  165. duration: 15,
  166. closable: true,
  167. });
  168. }
  169. }
  170. return Promise.reject(error);
  171. }
  172. );
  173. qmInstance.defaults.withCredentials = true; //允许跨域携带cookie
  174. qmInstance.defaults.timeout = 30 * 1000; //超时时间
  175. qmInstance.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest"; //标识这是一个 ajax 请求
  176. qmInstance.get = cachingGet(qmInstance.get, [
  177. /\/api\/exam_question\/question\/\?question_id/,
  178. /\/api\/exam_question\/paper_struct\/\?exam_record_id=/,
  179. /\/api\/ecs_oe_student\/examQuestion\/getQuestionContent\?questionId=.*&exam_record_id=/,
  180. /\/api\/ecs_exam_work\/exam\/\d+$/,
  181. /\/api\/ecs_oe_student_face\/upyun$/,
  182. /\/api\/ecs_oe_student\/examFaceLivenessVerify\/checkFaceLiveness$/,
  183. ]);
  184. loadProgressBar(qmInstance);
  185. // const upyunInstance = axios.create({});
  186. // // FIXME: axios bug. wait 0.19 release. https://github.com/axios/axios/issues/385
  187. // upyunInstance.defaults.headers.common = {};
  188. // // upyunInstance.defaults.headers.common["Authorization"] = UPYUN_HEADER_AUTH;
  189. // let __upyunAuth = null;
  190. // let __upyunBucketUrl = null;
  191. // upyunInstance.interceptors.request.use(
  192. // config => {
  193. // if (__upyunAuth) {
  194. // config.baseURL = __upyunBucketUrl;
  195. // config.headers.common["Authorization"] = __upyunAuth;
  196. // return config;
  197. // } else {
  198. // return qmInstance
  199. // .get("/api/ecs_oe_student_face/upyun")
  200. // .then(res => {
  201. // __upyunBucketUrl = res.data.bucketUrl;
  202. // config.baseURL = __upyunBucketUrl;
  203. // const authorization =
  204. // "Basic " +
  205. // btoa(atob(res.data.upyunOperator) + ":" + atob(res.data.upyunCred));
  206. // __upyunAuth = authorization;
  207. // config.headers.common["Authorization"] = __upyunAuth;
  208. // return config;
  209. // })
  210. // .catch(err => {
  211. // console.log(err);
  212. // });
  213. // }
  214. // },
  215. // error => {
  216. // Message.error({
  217. // content: error,
  218. // duration: 10,
  219. // closable: true
  220. // });
  221. // return Promise.resolve(error);
  222. // }
  223. // );
  224. // loadProgressBar(upyunInstance);
  225. Vue.prototype.$http = qmInstance;
  226. // Vue.prototype.$upyunhttp = upyunInstance;
  227. export default {
  228. install: function(Vue) {
  229. Object.defineProperty(Vue.prototype, "$http", {
  230. value: qmInstance,
  231. });
  232. // Object.defineProperty(Vue.prototype, "$upyunhttp", {
  233. // value: upyunInstance
  234. // });
  235. },
  236. };