1、问题现象

  页面长时间未操作,再刷新页面时,第一次弹出“token失效,请重新登录!”提示,然后跳转到登录页面,接下来又弹出了n个“Token已过期”的后端返回消息提示。

2、原因分析

  当前页面初始化,有多个向后端查询系统参数的调用,代码如下:

  created () {
// ========================================================================
// 获取需要的系统参数,注意:getParameterClass方法是异步加载数据的。
// 如需要打印观察,需要通过watch来处理 // 获取用户类型的参数类别
this.commonFuncs.getParameterClass(this,"user_type","userTypeList","userTypeMap"); // 获取用户状态的参数类别
for(var i = 0; i < this.userStatusList.length; i++){
var item = this.userStatusList[i];
var mapKey = parseInt(item.itemKey);
this.userStatusMap.set(mapKey, item);
} // 获取性别的参数类别
this.commonFuncs.getParameterClass(this,"gender","","genderMap"); // 获取部门的参数类别
this.commonFuncs.getParameterClass(this,"department","","deptMap"); // 获取角色的参数类别
this.commonFuncs.getParameterClass(this,"role","","roleMap"); // 查询用户记录
this.queryUsers();
},

  这些请求,是axios调用,是异步执行的,因此,刷新页面时,这些请求几乎立即就发出了。然后,这些请求的响应会陆续返回。

  响应首先被下面的response拦截器处理:

// token相关的response拦截器
instance.interceptors.response.use(response => {
if (response) {
switch (response.data.code) {
case 3: //token为空
case 4: //token过期
case 5: //token不正确
localStorage.clear(); //删除用户信息
alert('token失效,请重新登录!');
// 要跳转登陆页
router.replace({
path: '/login',
});
break;
case 6: //禁止访问
// 跳到403页面
router.replace({
path: '/forbidden',
});
break;
default:
break;
}
}
return response;
}, error => {
return Promise.reject(error.response.data.message) //返回接口返回的错误信息
})

  然后再进入请求调用处的代码:

    this.instance.getParameterClass(
this.$baseUrl, {"classKey" : classKey}
).then(res => {
//console.log(res.data);
if (res.data.code == parent.global.SucessRequstCode){
// 如果查询成功
// 成功的处理代码...
}else{
alert(res.data.message);
}
}).catch(error => {
//alert('查询系统参数失败!');
console.log(error);
});

  现在的问题:

  1. 对应一个请求,如果token过期,reponse拦截器首先弹出告警提示,然后,调用处又有提示:

    alert(res.data.message);

    这样就重复了。

  2. 对于同时发出的多个请求,需要有标记来记住这次token过期是否已提示,只提示一次,如已提示,就不必再提示。

3、解决方案

3.1、消除拦截器和请求调用处对token过期的重复提示

  编写一个公共方法,检查是否是被拦截处理的返回码,放于/src/common/commonFuncs.js文件中,代码如下:

  /**
* 判断是否被拦截处理的返回码,返回true,表示被拦截
* 此方法的作用是调用处,无需处理被拦截的返回码的错误提示
* @param {请求的返回码} code
*/
isInterceptorCode(code){
switch (code) {
case 3: //token为空
case 4: //token过期
case 5: //token不正确
case 6: //禁止访问
return true;
default:
break;
}
return false;
}

  然后所有调用处,针对非成功返回的处理均改为:

        if (!this.commonFuncs.isInterceptorCode(res.data.code)){
alert(res.data.message);
}

  这样,消除了拦截处理和调用处理的重复告警。

3.2、多个请求只提示一次的处理

  在全局变量文件/src/common/global.js中,增加token无效标记,代码如下:

//全局变量

export default {
// 请求成功返回码
SucessRequstCode:0, // token无效标记
TokenInvalidFlag : 0
}

  然后,修改拦截器代码:

// token相关的response拦截器
instance.interceptors.response.use(response => {
if (response) {
switch (response.data.code) {
case 0: //正常
// 复位token无效标记置
global.TokenInvalidFlag = 0;
break;
case 3: //token为空
case 4: //token过期
case 5: //token不正确
localStorage.clear(); //删除用户信息
if (global.TokenInvalidCounter == 0){
alert('token失效,请重新登录!');
}
// token无效标记置1
global.TokenInvalidFlag = 1; // 要跳转登陆页
router.replace({
path: '/login',
});
break;
case 6: //禁止访问
// 跳到403页面
router.replace({
path: '/forbidden',
});
break;
default:
break;
}
}
return response;
}, error => {
return Promise.reject(error.response.data.message) //返回接口返回的错误信息
})

  即在第一次收到token过期消息(此时TokenInvalidFlag=0)时,进行提示,然后设置为1(此时TokenInvalidFlag=1),后续的若干个请求的响应,都不会在告警提示了。直到收到成功返回码时复位为0,此时表示重新登录成功了。

  经测试,这样处理达到预期效果,即token过期时,刷新页面,只提示一次告警。

最新文章

  1. python中__init__问题
  2. ubuntu mysql emma中文乱码问题解决
  3. css清除默认样式和设置公共样式
  4. 利用 Oracle EM 企业管理器 进行oracle SQL的优化(自动生成索引)
  5. 配置安装theano环境(非GPU版)
  6. heibernate增删改查总结一下自己的不足
  7. iOS 使用pods报错问题 pod --version
  8. mybatis逆向工程之生成文件解释
  9. [linux RedHat]windows下使用putty远程连接linux 下载JDK和tomcat
  10. ActiveMQ的作用总结(应用场景及优势)
  11. npm install报错Unhandled rejection RangeError: Maximum call stack size exceededill install
  12. CORS jsonp
  13. iOS逆向之TheOS
  14. Python才排第8名!2018增速最快TOP 10编程语言盘点
  15. redis 集群java.lang.NoSuchMethodError:SpringJAR包版本冲突错误解决方法
  16. nginx禁止非sever_name指定域名访问
  17. webpack究竟是什么
  18. 由OpenResty粘合的企业Web架构
  19. UnicodeEncodeError: &#39;gbk&#39; codec can&#39;t encode character ...
  20. SQL Server集成服务最佳实践:语句优化

热门文章

  1. 11.4 iftop:动态显示网络接口流量信息
  2. 把采集到的数据发送到一个Google Docs或者Google Form上 这个网站提供了参考和例子
  3. STM32 keil中编译遇到的问题
  4. python 判断对象是否相等以及eq函数
  5. hive的排序 order by和sort by
  6. SpringBoot基础学习(一) SpringBoot概念、简单案例实现、单元测试及热部署讲解
  7. l初识CSRF(跨站请求伪造)
  8. GPU微观物理结构框架
  9. Timer定时器开发
  10. 作为一名双非本科毕业的Java程序员,我该如何在日益严重的内卷化中避免被裁?