http.js 3.3 KB

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