基于axios针对物理返回键主动取消当前页面http请求及loading

最近遇到一个需求:就是在页面请求很久的情况下页面一直在loading状态,此时用户点击物理返回键需要取消掉loading及当前还在请求的接口。

  • axios提供取消功能
    由于整套http接口是基于axios来的,所以就去找了下官网的例子
    基于axios针对物理返回键主动取消当前页面http请求及loading_第1张图片
    axios取消

  • 主要思路
    设置一个全局对象来存储当前页面的页面名称,当前请求路径,当前请求可取消函数,在路由变了那么意味着页面变了,来整体清除当前存储的页面http信息。

  • axios请求拦截设置

// cancelHttpRequest为全局对象
// 调用cancelHttpRequest.set()来设置当前页面请求信息
// isShowLoading 为配置信息是否显示loading
import cancelHttpRequest from '../utils/cancelHttpRequest'
const CancelToken = axios.CancelToken;
_axios.interceptors.request.use(config => {

	isShowLoading &&
      Toast.loading({
        duration: 0,
        mask: false,
        forbidClick: true,
        message: '加载中...',
      });
      
	config.cancelToken = new CancelToken((c) => {
      cancelHttpRequest.set({
        curPage: router.history.current.name,
        requestUrl: config.url,
        func: c,
      });
    });
})
  • axios拦截响应头设置
_axios.interceptors.response.use(resp=>{
	// 你自己的相应逻辑
},error=>{
	// 这里重点在err的时候处理
	// 清除toast
    Toast.clear();
    // 若手动取消http请求
    if (!!error.message && error.message === 'handleByBack') {
      return Promise.reject(error.message);
    }else{
	// 你其他业务错误或公共错误处理逻辑	
	} 
})
  • 路由afterEach执行清除
import cancelHttpRequest from '../utils/cancelHttpRequest'
router.afterEach((to, from) => {
	cancelHttpRequest.cancelHttp()
})
  • cancelHttpRequest.js
/**
 *  @module 针对http执行可取消操作封装
 *  @author ljxin
 *  @tips cancelHttpRequest对象
 *        私有变量 _dsHttp
 *        暴露方法: set ,get ,cancelHttp
 */
const cancelHttpRequest = {
  // 缓存当前页面的所有http请求
  _dsHttp: {},
  /**
   * @func 设置当前页面的http请求
   */
  set: (v) => {
    const { curPage, requestUrl, func } = v;
    // 判断当前http集合中是否已有数据
    if (Object.keys(cancelHttpRequest._dsHttp).length !== 0) {
      // 是否是同一个页面的请求
      const cur_dsHttpPage = cancelHttpRequest._dsHttp['curPage'];
      if (cur_dsHttpPage === curPage) {
        let reqObj = {};
        reqObj['requestUrl'] = requestUrl;
        reqObj['func'] = func;
        cancelHttpRequest._dsHttp['curReqInfo'].push(reqObj);
      }
    } else {
      // 直接存入
      cancelHttpRequest._dsHttp['curPage'] = curPage;
      cancelHttpRequest._dsHttp['curReqInfo'] = [];
      let reqObj = {};
      reqObj['requestUrl'] = requestUrl;
      reqObj['func'] = func;
      cancelHttpRequest._dsHttp['curReqInfo'].push(reqObj);
    }
    // console.log('当前请求集合',cancelHttpRequest._dsHttp)
  },
  /**
   * @func 获取当前http请求集合
   */
  get: () => {
    return cancelHttpRequest._dsHttp;
  },
  /**
   * @func 取消当前页面的所有http请求
   */
  cancelHttp: () => {
    if (Object.keys(cancelHttpRequest._dsHttp).length !== 0) {
      if (cancelHttpRequest._dsHttp['curReqInfo'].length !== 0) {
        const cancelDs = cancelHttpRequest._dsHttp['curReqInfo'];
        cancelDs.map((el) => {
        // 这里会响应:响应拦截的error
          el.func('handleByBack');
        });
        // 重置集合
        cancelHttpRequest._dsHttp = {};
      }
    }
  },
};

export default cancelHttpRequest;

你可能感兴趣的:(vue,axios,取消http请求,物理返回键,取消loading)