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

1、问题现象

水桃小说网 https://www.1752.info

  页面长时间未操作,再刷新页面时,第一次弹出“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过期时,刷新页面,只提示一次告警。

Vue中,可以通过使用Axios库来实现token过期自动刷新的功能。首先,在前端代码中,可以使用Axios的封装来发送请求,并在请求中携带token。当token过期,接口会返回401状态码。此,前端可以通过拿着refreshToken去刷新token,获取新的token和refreshToken,并将token过期的请求重新发起,实现自动刷新token的效果。\[2\] 在Vue中,可以在Axios的响应拦截器中判断http状态是否为401。如果是401状态码,说明token过期,此可以使用refreshToken去调用接口,接口会返回新的token和refreshToken。然后,将新的token和refreshTokenVuex中重新赋值。接着,可以继续调用之前报401的接口,这次使用新的token去请求就可以了。\[3\] 通过以上的方法,可以在Vue中实现token过期自动刷新的功能。这样,在用户没有任何感知的情况下,可以自动刷新token,保证用户的登录状态。 #### 引用[.reference_title] - *1* [【Token+Vue3】token无感刷新 | token自动刷新 | token过期](https://blog.csdn.net/qq_43614372/article/details/131387406)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [token过期后刷新token并重新发起请求](https://blog.csdn.net/weixin_44886911/article/details/124992704)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [vue token过期后自动刷新token](https://blog.csdn.net/cai_niao5623/article/details/124104932)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值