axios 实现 无感刷新方案

  1. 实现思路

    1. 首次登录前端通过接口获取到两个 token;分别是 accessToken、refreshToken;
    2. accessToken:正常请求需要传递的 token ;
    3. refreshToken:当某个请求 401 ,就可以通过 refreshToken 获取到新的 accessToken
    4. 特殊场景:如果 refreshToken 也过期了 ,那就默认跳回 登录页,重新登录,就类似 七天免登录的场景、过了 第七天,refreshToken 也就过期了;
  2. 代码
    1.

    javascript 复制代码
    import axios from "axios";
    import { refreshToken } from "../api/index"; //刷新token的api
    let isRefreshToken = false; //是否正在进行刷新token
    let requestList = []; // 请求队列
    
    const request = axios.create({
      baseURL: "/api",
      timeout: 10000,
    });
    
    // 请求拦截器
    request.interceptors.request.use(
      (config) => {
        let headerToken = localStorage.getItem("acc_token");
        // 设置请求头
        config.headers.Authorization = `Bearer ${headerToken}`;
        return config;
      },
      (error) => {
        // 请求错误时做些事
        return Promise.reject(error);
      }
    );
    
    // 响应拦截器
    request.interceptors.response.use(
      async (response) => {
        // 401 代表token过期,需要刷新token
        if (response.data.code == 401) {
          // 这里可以加入判断,判断 refreshToken 也过期了,直接 router.push 回登录页
          // if () {
          // router.push('/login')
          // }
          if (!isRefreshToken) {
            isRefreshToken = true;
            let res = await refreshToken(); // 刷新 token 的接口
            isRefreshToken = false;
            localStorage.setItem("acc_token", res.data.accToken);
            //   重发请求队列请求
            requestList.forEach((callback) => {
              callback();
            });
            requestList = [];
    
            let currentRequest = await request(response.config);
            return currentRequest;
          } else {
            // 将并发的请求,通过回调函数暂存起来,当token 刷新之后,在进行请求
            return new Promise((resolve) => {
              requestList.push(() => {
                resolve(request(response.config));
              });
            });
          }
        }
        return response;
      },
      (error) => {
        return Promise.reject(error);
      }
    );
    
    export default request;
相关推荐
雪芽蓝域zzs13 分钟前
第二十二节:进阶:用户管理新增、编辑弹窗 + 表单校验
前端·javascript·vue.js
IT_陈寒18 分钟前
Java字符串判等踩坑记:==和equals真的不能乱用
前端·人工智能·后端
晴天1629 分钟前
前端虚拟滚动(虚拟列表)原理与实战
前端
晴天1643 分钟前
前端 RAIL 性能模型实战分享-Day37
前端
变与不变8061 小时前
JS作用域,作用域链
前端·javascript·es6
知兀1 小时前
Tailwindcss报错:没有与此调用匹配的重载
前端·c++·tailwindcss
晴天161 小时前
Chrome WebMCP 让网站学会向 AI「自我介绍」
前端·人工智能·chrome
雪芽蓝域zzs1 小时前
二十一节:进阶:用户列表批量删除功能
前端·javascript·vue.js
研☆香1 小时前
可选链运算符和空值合并运算符的使用
前端·javascript·vue.js
leeyi1 小时前
SSE 到了浏览器会怎样:解析、重连与中止(第105篇)
前端