• Vue 消除Token过期时刷新页面的重复提示


    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不正确    
            if (global.TokenInvalidFlag == 0){
              //删除用户信息
              localStorage.clear();  
              // 告警提示   
              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过期时,刷新页面,只提示一次告警。

    作者:阿拉伯1999
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
    养成良好习惯,好文章随手顶一下。
  • 相关阅读:
    IP子网掩码格式转换
    错误: symbol lookup error: /usr/local/lib/libreadline.so.6: undefined symbol: PC
    postgresql删除属性
    postgresql 修改属性
    嵌套json的查询
    嵌套json
    关于array_agg 函数
    修改jsonb的属性
    Python中exec的使用
    RHSA-2017:2930-重要: 内核 安全和BUG修复更新(需要重启、存在EXP、本地提权、代码执行)
  • 原文地址:https://www.cnblogs.com/alabo1999/p/14983429.html
Copyright © 2020-2023  润新知