vue无感刷新Token并重新请求

server/2024/9/23 15:33:10/

vue 拦截器拦截401重新请求Token 无感刷新Token 之后重新请求报401的接口

javascript">instance.interceptors.response.use(async (response) => {let { data } = response;if (data.code === 401 || data.code === 403) {return await handleExpiredToken(response.config);}if (data.code !== 200) {return Promise.reject(data);} else {return Promise.resolve(data);}},async (error) => {if (!error || !error.response) {handleNetworkError();return Promise.reject('Network anomaly');}switch (error.response.status) {case 401:case 403:return await handleExpiredToken(error.config);case 500:handleServerError(error.response.data.code);break;case 502:Message.error('Server error');break;default:break;}return Promise.reject(error.response.data.message);}
);let isRefreshing = false;
let pendingRequests = [];/// 处理 Token 过期
const handleExpiredToken = async (originalRequest) => {if (isRefreshing) {// 如果正在刷新 Token,将请求推入队列等待return new Promise((resolve, reject) => {pendingRequests.push({ originalRequest, resolve, reject });});}isRefreshing = true; // 标记为正在刷新// 请求新的 tokentry {const params = {refreshToken: localStorage.getItem('refreshToken'),grantType: 'refreshToken'};// 刷新Token接口const response = await login(params);const { accessToken, refreshToken } = response.data;localStorage.setItem('token', accessToken);localStorage.setItem('refreshToken', refreshToken);// 处理通过原请求重试其他待处理请求processPendingRequests(accessToken);// 更新原请求的 Authorization 头originalRequest.headers['Authorization'] = `Bearer ${accessToken}`;// 重新发送原请求return await instance(originalRequest);} catch (error) {console.log('error--------', error);localStorage.clear();router.push('/login');// 清空待处理请求队列processPendingRequests(null);} finally {isRefreshing = false; // 清理标记}
}// 处理待处理请求
const processPendingRequests = (accessToken) => {pendingRequests.forEach(({ originalRequest, resolve, reject }) => {if (accessToken) {// 更新请求的头部originalRequest.headers['Authorization'] = `Bearer ${accessToken}`;resolve(instance(originalRequest));} else {reject('Token refresh failed');}});// 清空队列pendingRequests = [];
};

http://www.ppmy.cn/server/120853.html

相关文章

js笔记(第二章)

Number 在js中所有的数值都是Number类型,包括整数和浮点数(小数) js中可以表示最大值 console.log(Number.MAX_VALUE) 输出结果中,最大的后边的7e308是科学计数法,表示e后边有308位 如果想要更大的值…

Writeset

优质博文:IT-BLOG-CN MySQL的WriteSet功能主要用于增强复制的并发性和一致性,特别是在主从复制环境中。WriteSet是MySQL 5.7引入的一个特性,主要用于解决复制过程中可能出现的写冲突问题。 MySQL并行复制目前经历过三个比较关键的时间结点“…

知乎:从零开始做自动驾驶定位; 注释详解(一)

消息发布与订阅 目录 消息发布与订阅缓冲区机制CMakeLists文件规划*注释参考链接 1. 消息发布与订阅 消息的订阅和发布,这是每个ROS工程都必备的东西,我们常见的使用方式是在main函数中定义subscriber和publisher,每个subscriber会有一个cal…

等保测评与网络安全等级划分

等保测评与网络安全等级划分的关系 等保测评(信息安全等级保护测评)是根据国家信息安全等级保护制度,对信息系统进行安全等级评定的活动。它旨在确保信息系统能够抵御各种安全威胁,保障信息的机密性、完整性和可用性。网络安全等级…

旷视轻量化网络shufflenet算法解读

目录 预备知识 1. 回顾MobileNet V1的核心思想---深度可分离卷积 2.ShuffleNet主要有两个创新点 2.1 分组卷积与11分组卷积 2.2 channel Shuffle(通道重排) 2.3 通道重排过程 3. ShuffleNet网络结构 3.1 ShuffleNet unit 3.2 不同分组数的Shu…

Real-Time Linux 合并到内核主线

在长达 20 年之后,Real-Time Linux(PREEMPT_RT)合并到内核主线。 从 Linux 6.12 开始,所有发行版都将包含实时 Linux 代码。 这意味着 Linux 将开始运行在更多任务关键设备和工业硬件上。实时操作系统对时间限制非常严格,需要确保关键任务在…

智能BI项目第一期

该项目是全程跟着鱼皮,还未进行功能扩展。为了方便日后复习,打算将一些重要的步骤记录下来。 项目概述 BI:即商业智能:Business Intelligence 过去 需要手动导入数据、选择要分析的字段和图表,并由专业的数据分析师完成分析,最后得出结论。 现在 用户…

【测试】——Selenium API (万字详解)

📖 前言:本文详细介绍了如何利用Selenium进行Web自动化测试,包括定位元素(如cssSelector和xpath)、常用操作函数(如点击、输入等)、窗口管理、键盘鼠标事件和浏览器导航,以及处理弹窗…