美文网首页
登录失效后,出现多个请求失败的土司提示/切换路由时,取消上一个页

登录失效后,出现多个请求失败的土司提示/切换路由时,取消上一个页

作者: 前端青音 | 来源:发表于2020-05-11 12:00 被阅读0次

    【问题】:

    登录超时后,自动跳到登录页,出现多个请求失败的土司提示

    【原因】:

    点击页面发送请求,当后端检测到登录失效后,会返回特定的状态码,出现请求超时的提示,前端拦截对应的状态码,登出跳到登录页。点击页面发送请求时,可能会同时发起多个请求,导致的。

    【解决方案】:

    当切换路由时,取消上一个页面的所有请求。

    代码:

    在axios封装页面中,添加一个变量axiosPromiseArr存放cancel方法,当切换路由的时候,调用。
    axios.js

    import axios from 'axios'
    import qs from 'qs'
    import store from '@/store'
    import router from '@/router'
    
    // import { Message } from 'element-ui'
    import { host } from '@/__conf'
    let axiosPromiseArr = []
    
    const httpRequest = axios.create({
      baseURL: process.env.NODE_ENV === 'production' ? host : '',
      timeout: 60000
    })
    
    // 请求拦截
    httpRequest.interceptors.request.use(
      function (config) {
        config.cancelToken = new axios.CancelToken(cancel => {
          axiosPromiseArr.push({ cancel })
        })
        // token
        if (store.state.token) {
          config.headers['Authorization'] = store.state.token
        }
        if (
          config.method === 'post' &&
          config.data &&
          config.headers['Content-Type'] !== 'application/json' &&
          config.headers['Content-Type'] !== 'multipart/form-data'
        ) {
          config.data = qs.stringify(config.data)
        }
        return config
      },
      function (error) {
        return Promise.reject(error)
      }
    )
    
    // 响应拦截
    httpRequest.interceptors.response.use(
      function (response) {
        let code = response.data.code
        let whiteList = [0, 200]
        if (whiteList.includes(code)) {
          return response.data
        }
        // 跳转到登录页面
        if (
          [
            10005,
            500000,
            500001,
            500002,
            500003,
            500004,
            600000,
            600001,
            150000,
            100001,
            20003
          ].includes(code)
        ) {
          store.commit('logout')
          router.push('/login')
        }
        // Message({ type: 'error', message: response.data.msg })
        return Promise.reject(response.data)
      },
      function (error) {
        // Message({ type: 'error', message: 'hhhhhhh' })
        if (error && error.message) {
          if (error.message === 'timeout of 10000ms exceeded') {
            return Promise.reject(error)
          }
          return new Promise(() => { })
        }
        console.log(error)
        return Promise.reject(error)
      }
    )
    
    export { httpRequest, axiosPromiseArr }
    
    

    在main.js中,路由前置守卫中遍历取消所有请求
    main.js

    import { axiosPromiseArr } from '@/lib/axios'
    router.beforeEach((to, from, next) => {
      // title
      axiosPromiseArr.forEach((ele, index) => {
        ele.cancel('我中断一个请求康康')
        delete axiosPromiseArr[index]
      }) 
      next()
    })
    

    【总结】:

    将发起的所有请求,都存于axiosPromiseArr,并且给其挂载cancel方法。切换路由时会触发router.beforeEach 路由前置守卫,在该路由钩子函数中,调用所有请求的cancel方法,取消请求。

    相关文章

      网友评论

          本文标题:登录失效后,出现多个请求失败的土司提示/切换路由时,取消上一个页

          本文链接:https://www.haomeiwen.com/subject/atwynhtx.html