vue2数据可视化大屏axios token过期刷新token方法

vue yekong

数据可视化大屏项目开发中,项目的token有效期很短,这时候我们就需要使用刷新令牌进行token刷新,当接口code为401的时候,我们需要记录这些报401的接口,然后进行token刷新,刷新完成后,重新请求之前报401的接口以刷新数据。如果token刷新失败的话就直接跳转到登录页。

请求方法封装

import axios from 'axios'
// import {Message} from 'element-ui'
import {devIp} from '@/api/ipConfig'
import router from '@/router'
import {Message} from "element-ui";
import {refreshToken} from "@/api/api/LargeScreenData"; // 确保正确引入了router
// 刷新token的一个开关,防止重复请求
let isRefreshing = true;
let requestList = []
const service = axios.create({
  baseURL: devIp + '', // 测试IP
  timeout: 100000, // request timeout
})

// request interceptor
service.interceptors.request.use(config => {
  config.headers['tenant-id'] = 1
  let token = localStorage.getItem('accessToken')
  // 后续接口请求头都需要加上 Authorization,   Authorization='Bearer ' + accessToken
  config.headers['Content-Type'] = 'application/json';
  if (token) {
    config.headers['Authorization'] = 'Bearer ' + token // 让每个请求携带token-- ['X-Token']为自定义key 请根据实际情况自行修改
  }
  return config
}, error => {
  Promise.reject(error)
})
// 假设这个变量在合适的地方被定义
let isMessageShowing = false;
// respone interceptor
service.interceptors.response.use(
  // response => response,
  async response => {
    const res = response.data

    if (res.code == 401) {
      const originalConfig = response.config;
      isRefreshing = true;
      try {
        let refreshTokenData = localStorage.getItem('refreshToken');

// 调用 refreshToken 函数,传递当前的 refreshToken
        const refreshTokenRes = await refreshToken({refreshToken: refreshTokenData});

// 从接口返回的数据中解构出新的 accessToken 和 refreshToken
        const {accessToken, refreshToken: newRefreshToken} = refreshTokenRes.data;

// 更新本地存储中的 accessToken 和 refreshToken
        localStorage.setItem('accessToken', accessToken);
        localStorage.setItem('refreshToken', newRefreshToken);
        isRefreshing = false;

        // 重新发起队列中的请求
        requestList.forEach(cb => cb(accessToken));
        requestList = [];

        return service(originalConfig); // 用新的令牌重新发起失败的请求
      } catch (refreshError) {
        // 刷新令牌失败的处理逻辑...
        // console.error('无法刷新令牌,需要重新登录', refreshError);
        Message.error({
          message: '登录状态已过期,请重新登录',
          onClose: () => {
            isMessageShowing = false; // 当消息关闭时,重置标志
          }
        });
        localStorage.removeItem('accessToken');
        router.push('/login');
        // 清理登录状态,重定向到登录页...
        return Promise.reject(refreshError);
      } finally {
        isRefreshing = false;
      }
    } else if (res.code == 500) {
      if (!isMessageShowing) {
        isMessageShowing = true;
        Message.error({
          message: res.msg || '发生错误,请稍后再试',
          onClose: () => {
            isMessageShowing = false; // 当消息关闭时,重置标志
          }
        });
      }
    }
    return res;
  },
  async error => {
    // 其他错误处理逻辑...
    return Promise.reject(error);
  }
)

export default service

避免多次弹出重复提示

当我们进行接口请求的时候,如果请求多个接口都报错的时候,会弹出多个错误提示,这样很不友好,我们需要的是每次只弹出一个错误提示。

elementui Message.error一次只出现一个提示信息避免同时弹出多个错误信息

喜欢