夸克之书

  • 首页
  • 科普
  • 笔记
  • C#
  • 物联网
  • 算法
  • Linux
  • 树莓派
夸克之内,别有洞天
  1. 首页
  2. 默认
  3. 正文

解决js异步同时请求接口的问题

2021-08-20 1569点热度 0人点赞 0条评论

最近在实现refesh token,但是在前端页面请求刷新的时候遇到一个问题。

场景如下:刷新页面时,同时有几个接口在进行请求,由于refesh token的操作放在拦截器中,在接口请求时,判断当前token是否过期,如果token过期之后,进行token刷新操作。可想而知会发生什么问题。几个接口争先恐后的去使用refesh_token换取新的token,跑的快的,成功拿到新的token。跑的慢,只有拿第一个接口用过的refesh_token去刷新,服务器看到递过来的是已经用过了的 refesh_token,只有毫不犹豫的拒绝。

%title插图%num
请求失败

所以就需要一个机制,让换取token的操作依次执行,或者只需要执行一次。让第一次执行刷新token之后,后面接口发现token已经被刷新了,就不在去刷新token。

这时候就可以利用js Promise链式调用的特点去解决这个问题。具体思路就是返回Promise对象,通过调用Promise的then函数,返回需要的内容。具体原理的话,我描述不清楚,因为也是是个前端小菜鸡啊~~~所以有啥错误的地方,还请多多指教和包含。

上代码:

1、拦截器中判断token是否过期,过期就操作刷新

    let token = store.getters["account/token"];
    let timeNow = Math.round(new Date().getTime() / 1000);
    if (!requestUrlInIgnoreList(url) && (!token || token.expires_at - 60 <= timeNow)) {
      console.log("[Local]AccessToken expiring, start refresh token...");
      let newToken = await localRefreshToken();
      if (newToken) {
        console.log("[Local]Refresh successful, token is " + JSON.stringify(newToken));
        config.headers.Authorization = `Bearer ${newToken.access_token}`;
      } else {
        message.warning("认证已过期,请重新登录");
      }
    } else {
      if (!requestUrlInIgnoreList(url)) {
        config.headers.Authorization = `Bearer ${token.access_token}`;
      }
    }

2、token刷新类

class localAccount {
  refreshTokenPromise = null;

  refreshToken = async () => {
    if (this.refreshTokenPromise) {
      console.log("我是后来的,我也要刷新token...");
      return this.refreshTokenPromise.then(() => {
        let lastRefeshToken = store.getters["account/token"];
        return lastRefeshToken;
      });
    }
    let newToken = undefined;
    let oldToken = store.getters["account/token"];
    if (!oldToken || !oldToken.refresh_token) {
      return newToken;
    }
    this.refreshTokenPromise = request(POST_REFESH, METHOD.POST, {
      Token: oldToken.refresh_token,
    })
      .then((result) => {
        if (result && result.data.code == 0) {
          let userToken = {
            access_token: result.data.data.accessToken,
            refresh_token: result.data.data.refreshToken,
            token_type: result.data.data.tokenType,
            expires_at: result.data.data.expiresAt,
            profile: result.data.data.profile,
          };
          newToken = userToken;
          //设置用户
          if (newToken) {
            store.commit("account/setToken", newToken);
          }
          this.refreshTokenPromise = null;
          return newToken;
        }
      })
      .catch((err) => {
        console.error(err);
      });
    return this.refreshTokenPromise;
  };
}

通过定义一个全局的 refreshTokenPromise 对象,第一次请求时, refreshTokenPromise 对象为空,进行token刷新。由于封装的request本身也是一个异步请求,所以将request赋值给 refreshTokenPromise 。所以当第二个刷新请求过来之后,判断 refreshTokenPromise 是否为空,不为空的话,表示正在请求。使用then方法,返回从store取出第一次请求更新的token。

本作品采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可
标签: 暂无
最后更新:2022-01-25

afirefish

这个人很懒,什么都没留下

打赏 点赞
< 上一篇
下一篇 >

文章评论

您需要 登录 之后才可以评论
放松一下
https://www.quarkbook.com/wp-content/uploads/2021/05/凤凰传奇-海底(Live).flac
分类
  • C#
  • Linux
  • 树莓派
  • 物联网
  • 科普
  • 笔记
  • 算法
  • 默认
最新 热点 随机
最新 热点 随机
Windows移除多余输入法'Unknown Locale (qaa-Latn)' 【算法】具有层级关系的城市,例如"中国 广州","中国 浙江 杭州" 一个 List 最后应该是转成树状图输出 树莓派安装Golang环境 树莓派 Zero USB/以太网方式连接配置教程 树莓派Zero 2 w超频 PVE使用山克UPS(ViewPower)
解决Visual Studio 2022中无法编译 .NET Framework 4.5/4.5.1项目(Visual Studio 2022安装.NET Framework 4.5)PVE使用山克UPS(ViewPower)树莓派Zero 2 w超频树莓派 Zero USB/以太网方式连接配置教程树莓派安装Golang环境【算法】具有层级关系的城市,例如"中国 广州","中国 浙江 杭州" 一个 List 最后应该是转成树状图输出
战地 Origin发生了些意料之外的事情解决方法 MSBuild 构建选项,将项目文件复制到输出目录当中 树莓派自动化推流摄像头到Bilibili直播 近期学习计划整理 Ubuntu18.04安装Docker .Net Core在Linux下操作图片报错
最近评论
去月球 发布于 4 个月前(01月17日) 如果使用CSI的摄像头应该怎么修改命令呢
Me 发布于 5 个月前(12月31日) 好像还得写启动项 要不重启就还原了。
十三 发布于 5 个月前(12月23日) 大神,网盘链接失效了,重新分享一下吧,
一键快乐 发布于 11 个月前(07月09日) 老哥 我替换之后能进去了但是网络和声音上有两个×怎么办
翩翩蒯公子 Maxwell 发布于 1 年前(05月15日) 赞一个,挺好的文章。
书签
  • 打赏
  • 毒鸡汤(有点意思)
  • 米店
  • 金鱼直播间

COPYRIGHT © 2022 quarkbook.com. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

蜀ICP备15036129号-9

登录
注册|忘记密码?