vue 配置axios,增加被挤下线以后中断后续请求

实际测试的时候如果有多个并发请求,因为登录被挤掉了,所以被后端拦截器直接处理返回了-9991状态码,响应时间相差无几,会出现多次弹出去登录的确认框。所以源码里我也加入了防止重复多次弹出提示的限制。 

import Axios from 'axios'
import Config from '../config/config-1'
import { Notification, Loading, MessageBox } from 'element-ui'

let isShowConfirm = false
const service = Axios.create({
  baseURL: Config.apiUrl + '/' + Config.apiPrefix,
  headers: {
    'Content-Type': 'application/json; charset=UTF-8'
  },
  withCredentials: true,
  // `responseType` 表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
  responseType: 'json', // 默认的
  timeout: Config.timeout
})
service.defaults.retry = Config.requestRetry // 重试次数
service.defaults.retryDelay = Config.requestRetryDelay // 重试延时

const CancelToken = Axios.CancelToken
var cancel

service.interceptors.request.use(
  config => {
    if (!config.closeLoading) {
      window.loadingInstance = Loading.service({
        lock: true,
        text: '加载中……',
        spinner: 'el-icon-loading',
        background: 'rgba(255, 255, 255, .01)'
        // target: document.querySelector('.loading-area')
      })
      // 创建一个计数器,主要是解决速度太快,并发请求导致遮罩(单例)提前关闭问题
      if (!window.count) {
        window.count = 1
      } else {
        window.count++
      }
      console.log(window.count)
    }

    let token = sessionStorage.getItem('token')
    if (token) {
      config.headers.common['Authorization'] = token
    }
    config.cancelToken = new CancelToken(function executor (c) {
      // executor 函数接收一个 cancel 函数作为参数
      cancel = c
    })
    return config
  },
  error => {
    Promise.reject(error)
  }
)

service.interceptors.response.use(
  response => { // Grade
    if (!response.config.closeLoading) {
      setTimeout(_ => {
        // 计数器,主要是解决速度太快,并发请求导致遮罩(单例)提前关闭问题
        if (window.count) {
          window.count--
          if (window.count === 0) {
            window.loadingInstance.close()
          }
          console.log(window.count)
        }
      }, 400)
    }
    const res = response
    if (res.status !== 200) {
      Notification({
        title: '数据返回出错',
        message: '请稍后重试',
        type: 'warning'
      })
      // return Promise.reject('error')
    } else {
      if ((res.config).hasOwnProperty('closeInterceptors') && res.config.closeInterceptors) {
        return res.data
      }
      // 根据服务器返回的token进行更新操作
      if (res.headers.expired) {
        sessionStorage.setItem('token', res.headers.token)
        sessionStorage.setItem('expired', res.headers.expired)
      }

      // 下载操作
      if (res.headers['content-type'] === 'application/octet-stream') {
        return res.data
      }

      // console.log(res.data)
      if (res.data.code !== 10000) {
        if (res.data.code !== -9991) {
          Notification({
            title: res.data.message,
            type: 'warning'
          })
        }

        // 对响应数据做点什么,登录的时候保存["无登录",-9994],["登录时间过期",-9993]
        if (res.data.code === -9994 || res.data.code === -9993) {
          sessionStorage.setItem('token', null)
          sessionStorage.setItem('expired', null)
        }

        if (res.data.code === -9991) {
          cancel()
          if (isShowConfirm) return
          isShowConfirm = true
          MessageBox.confirm(res.data.message + '点击确定跳转到登陆页', '提示', {
            showClose: false,
            confirmButtonText: '确定',
            showCancelButton: false,
            closeOnClickModal: false,
            closeOnPressEscape: false,
            type: 'warning'
          }).then(res => {
            toLogin()
          })
        }
        if (res.data.code === -9994 || res.data.code === -9993) {
          toLogin()
        }
        // 自定义异常
        let ex = new Error()
        ex.status = res.status
        ex.code = res.data.code
        return Promise.reject(ex)
      }

      return res.data
    }
  },
  error => {
    setTimeout(_ => {
      window.loadingInstance.close()
      window.count = 0
    }, 400)
    if (!isShowConfirm) {
      // 如果弹出了其它地方登录,则不再提示请求错误
      Notification({
        title: '请求未响应',
        message: '服务器可能出了点问题',
        type: 'warning'
      })
    }
    // console.log(error)
    return Promise.reject(error)// 千万不能去掉,,,否则请求超时会进入到then方法,导致逻辑错误。
  }
)
function toLogin () {
  sessionStorage.removeItem('expired')
  sessionStorage.removeItem('token')
  sessionStorage.removeItem('permission')
  sessionStorage.removeItem('buttonPermission')
  window.location.href = '/login'
}
export default service

 

 

你可能感兴趣的:(个人笔记,vue,axios,中断请求)