ajaxVueVUE-全技术栈

axios拦截器只弹一次el-message 两种实现方法

2021-08-24  本文已影响0人  爱学习的小仙女早睡早起

场景说明:
用户登录后放置一段时间,或者在别处被使用,当该用户再次访问系统某页面,可能同时请求X个接口,此时接口报401或102等状态码,页面抛出错误。因为同时调用了多个接口,页面一次抛出好几个弹窗。


image.png

错误代码

import axios from 'axios'
import {Message} from 'element-ui'
const http = axios.create({
    timeout: 1000 * 60 * 2,
    withCredentials: true
})
// 当为post请求时设置其Content-Type为application/x-www-form-urlencoded
http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'

// 响应拦截
http.interceptors.response.use(res => {
    if (res.data.code === 102) {
        Message({
            message: '当前账号已经在其他客户端登录',
            type: 'warning',
        })
        // ... 这里执行清除token和跳转到登录页等操作
    }
)

解决办法1: 创建 messageOnce.js

// import {Message} from 'element-ui'
import { MessageBox  } from "element-ui";

// 私有属性,只在当前文件可用
const showMessage = Symbol('showMessage')
export default class domMessage {
    success (options, single = true) {  // Message方法
        this[showMessage]('success', options, single)
    }
    warning(options, single = true) {
        this[showMessage]('warning', options, single)
    }
    info(options, single = true) {
        this[showMessage]('info', options, single)
    }
    error(options, single = true) {
        this[showMessage]('error', options, single)
    }

    alert(options, single = true){
        this[showMessage]('error', options, single)
    }
    [showMessage] (type, options, single) {
        if (single) {
            // 关键代码,判断当前页是否有el-message标签,如果没有则执行弹窗操作
            if (document.getElementsByClassName('el-message-box').length === 0 || document.getElementsByClassName('el-message-box__wrapper')[0].style.display=="none" ) {
                MessageBox(options)
            }
        } else {
            MessageBox(options)
        }
    }
}

使用 messageOnce方法

import Vue from "vue";
import axios from "axios";
import router from "@/router";

import domMessage from './messageOnce'  // 引入方法
const messageOnce = new domMessage()

// 添加响应拦截器
axios.interceptors.response.use(
  (response) => {
    const data = response.data;
    if (data.code == 401) {
      messageOnce.alert({
        message: '登录信息不存在或已过期',
        title:'温馨提示',
        confirmButtonText: '确定',
        showClose:false,
        type: 'warning',
        callback: () => {
          sessionStorage.clear()
          router.push(`/login`);
        }
      })
    
      return data;
    } else if (data.status == 500) {
      messageBox({
        title: "",
        type: "warning-login",
        content: data.message,
        isSetTimeout: false,
      });
      return data;
    } else {
      return data;
    }
  },
  (error) => {
    var data =  error.response.data
    return Promise.reject(error);
  }
)

解决办法2
另一种思路是,在vueX中设置一个变量保存 过期标识 lateFlag
其他形式保存也行,自行发挥~~~

例如

  if (err.status === 401 ) {
      // 重新登陆
      if (lateFlag== 0) {
        lateFlag++
        MessageBox.confirm('很抱歉,登录已过期,请重新登录', {
          confirmButtonText: '重新登录',
          showCancelButton: false,
          type: 'warning'
        }).then(() => {
          db.remove('router')
          db.remove('loginToken')
          lateFlag= 0
          router.push({ path: '/login' });
        }).catch(()=>{
            aaa = 0
            // 确认框点了取消后  标识要复原 不然点了取消后再操作无法弹出登录超时提示
        });
      }
      return Promise.reject(error);
    }
注意: 确认框点了取消的回调事件 标识要复原 不然点了取消后再操作无法再弹出登录超时提示
上一篇下一篇

猜你喜欢

热点阅读