http.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import axios from "axios";
  2. import router from "../router";
  3. import { Message } from 'element-ui';
  4. let pending = []; //声明一个数组用于存储每个ajax请求的取消函数和ajax标识
  5. let cancelToken = axios.CancelToken;
  6. let removePending = (ever) => {
  7. for(let p in pending) {
  8. if(pending[p].u === ever.url + '&' + ever.method) { //当当前请求在数组中存在时执行函数体
  9. pending[p].f(); //执行取消操作
  10. pending.splice(p, 1); //把这条记录从数组中移除
  11. }
  12. }
  13. }
  14. // 创建axios实例
  15. var instance = axios.create({
  16. timeout: 1000 * 12,
  17. baseURL: 'http://192.168.1.165:8010'
  18. })
  19. // 请求拦截器
  20. instance.interceptors.request.use(
  21. config => {
  22. // 登录流程控制中,根据本地是否存在token判断用户的登录情况
  23. // 但是即使token存在,也有可能token是过期的,所以在每次的请求头中携带token
  24. // 后台根据携带的token判断用户的登录情况,并返回给我们对应的状态码
  25. // 而后我们可以在响应拦截器中,根据状态码进行一些统一的操作。
  26. const token = localStorage.getItem('accessToken')
  27. token && (config.headers.accessToken = token)
  28. removePending(config); //在一个ajax发送前执行一下取消操作
  29. config.cancelToken = new cancelToken((c)=>{
  30. // 这里的ajax标识我是用请求地址&请求方式拼接的字符串,当然你可以选择其他的一些方式
  31. pending.push({ u: config.url + '&' + config.method, f: c });
  32. });
  33. return config
  34. },
  35. error => Promise.error(error)
  36. )
  37. // 响应拦截器
  38. instance.interceptors.response.use(
  39. // 请求成功
  40. res => res.status === 200 ? Promise.resolve(res.data) : Promise.reject(res),
  41. // 请求失败
  42. error => {
  43. const { response } = error;
  44. if (response) {
  45. errorHandle(response.status, response.data.message);
  46. return Promise.reject(response);
  47. }
  48. }
  49. )
  50. /**
  51. * 跳转登录页
  52. * 携带当前页面路由,以期在登录页面完成登录后返回当前页面
  53. */
  54. const toLogin = () => {
  55. let path = '/';
  56. if(router.currentRoute.fullPath.indexOf('login') === -1) {
  57. path = router.currentRoute.fullPath
  58. }
  59. router.replace({
  60. path: '/login',
  61. query: {
  62. redirect: path
  63. }
  64. });
  65. }
  66. /**
  67. * 请求失败后的错误统一处理
  68. * @param {Number} status 请求失败的状态码
  69. */
  70. const errorHandle = (status, other) => {
  71. // 状态码判断
  72. switch (status) {
  73. // 401: 未登录状态,跳转登录页
  74. case 401:
  75. toLogin();
  76. break;
  77. // 403 token过期
  78. // 清除token并跳转登录页
  79. case 403:
  80. Message.error('登录过期,请重新登录');
  81. localStorage.removeItem('accessToken');
  82. localStorage.removeItem('UserName');
  83. localStorage.removeItem('UserId');
  84. setTimeout(() => {
  85. toLogin();
  86. }, 1000);
  87. break;
  88. // 404请求不存在
  89. case 404:
  90. Message.error('请求的资源不存在');
  91. break;
  92. case 500:
  93. Message.error('请求失败,请联系管理员');
  94. break;
  95. default:
  96. console.log(other);
  97. }}
  98. export default instance