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);
}