You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React SPA定时调用API刷新AccessToken的最优实现方案咨询

React SPA 固定间隔刷新AccessToken的最优方案

核心问题分析

你之前的实现会在页面刷新/路由切换后重置定时器,导致调用间隔被打乱。要实现登录后启动、不受页面刷新/路由跳转影响的固定5分钟调用,关键是要持久化记录上次调用时间,同时封装独立的定时器管理逻辑。

具体实现方案

1. 封装刷新Token的核心函数

const refreshAccessToken = async () => {
  try {
    const response = await fetch('/api/refresh-token', {
      method: 'POST',
      credentials: 'include' // 需携带Cookie时启用
    });
    const data = await response.json();
    
    // 更新本地存储的Token信息
    localStorage.setItem('accessToken', data.accessToken);
    // 记录本次刷新的时间戳
    localStorage.setItem('lastRefreshTime', Date.now().toString());
  } catch (error) {
    console.error('Token刷新失败:', error);
    // 失败处理:比如清除本地Token并跳转登录页
    localStorage.removeItem('accessToken');
    window.location.href = '/login';
  }
};

2. 封装定时器管理的自定义Hook

import { useEffect, useRef } from 'react';

const useTokenRefreshTimer = (isLoggedIn) => {
  const intervalRef = useRef(null);
  const REFRESH_INTERVAL = 5 * 60 * 1000; // 5分钟间隔

  useEffect(() => {
    // 未登录时清除定时器并清理记录
    if (!isLoggedIn) {
      if (intervalRef.current) {
        clearInterval(intervalRef.current);
        intervalRef.current = null;
      }
      localStorage.removeItem('lastRefreshTime');
      return;
    }

    // 计算首次调用的延迟时间:基于上次刷新时间补全剩余间隔
    const lastRefreshTime = parseInt(localStorage.getItem('lastRefreshTime') || Date.now().toString(), 10);
    const now = Date.now();
    const delay = Math.max(0, REFRESH_INTERVAL - (now - lastRefreshTime));

    // 启动定时器逻辑
    const startTimer = () => {
      // 先延迟执行首次刷新,再设置固定间隔
      const timeoutId = setTimeout(() => {
        refreshAccessToken();
        intervalRef.current = setInterval(refreshAccessToken, REFRESH_INTERVAL);
      }, delay);
      return () => clearTimeout(timeoutId);
    };

    const clearTimer = startTimer();

    // 组件卸载时清理定时器
    return () => {
      clearTimer();
      if (intervalRef.current) {
        clearInterval(intervalRef.current);
        intervalRef.current = null;
      }
    };
  }, [isLoggedIn]);
};

export default useTokenRefreshTimer;

3. 在根组件中使用Hook

import useTokenRefreshTimer from './hooks/useTokenRefreshTimer';

function App() {
  // 从本地存储判断登录状态(也可结合Redux/Zustand等状态管理)
  const isLoggedIn = !!localStorage.getItem('accessToken');

  // 挂载定时器逻辑
  useTokenRefreshTimer(isLoggedIn);

  return (
    <div className="App">
      {/* 你的路由与页面内容 */}
    </div>
  );
}

export default App;

关键细节说明

  • 持久化时间记录:通过localStorage存储上次刷新时间,页面刷新后能基于该时间计算剩余延迟,保证调用间隔严格为5分钟。
  • 登录状态联动:登录成功后自动启动定时器,退出登录时自动清除定时器与时间记录。
  • 异常处理:刷新失败时自动清理本地Token并跳转登录页,避免无效循环调用。

内容的提问来源于stack exchange,提问作者asallan3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 05:30:47