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

React中令牌认证路由刷新后跳转至404页面的问题

React中令牌认证路由刷新后跳转至404页面的问题

嗨,我来帮你分析下这个问题~ 从你提供的代码来看,刷新后跳转到404主要有两个核心原因,咱们一步步拆解:

问题根源分析

1. 初始认证状态的异步导致路由误匹配

你的isAuthenticated初始值是false,而检查localStorage令牌的逻辑放在了useEffect里——这个钩子是在组件第一次渲染完成后才执行的。刷新页面时会经历这样的流程:

  • 页面刷新,App组件初始化,isAuthenticated为false
  • 渲染未认证状态下的Routes,此时当前URL是/dashboard或/settings,未认证路由里没有匹配这两个路径的规则,于是触发path="*"的重定向,把URL改成/
  • 随后useEffect执行,拿到localStorage里的令牌,把isAuthenticated设为true
  • 此时渲染认证状态下的Routes,但URL已经被改成/了,而认证路由里没有path="/"的规则,所以匹配到path="*"的NotFound组件,最终显示404

2. 服务器未配置SPA fallback(针对BrowserRouter)

如果你用的是BrowserRouter(代码里的Router如果是它的别名),React Router是靠客户端路由匹配的。但刷新页面时,浏览器会直接向服务器请求/dashboard这个路径,如果服务器没有配置“任何未匹配的路径都返回React的index.html”,服务器就会返回404页面,这时候React都没机会加载,直接显示服务器的404。

解决方案

方案一:修复初始认证状态的路由逻辑

我们需要避免在认证状态确定前就错误重定向,推荐用路由守卫组件来统一控制受保护页面的访问权限,同时增加加载状态避免中间状态的路由误匹配:

第一步:创建ProtectedRoute路由守卫组件

const ProtectedRoute = ({ children }) => {
  const [isAuthenticated, setIsAuthenticated] = useState(false);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    const token = localStorage.getItem('token');
    setIsAuthenticated(!!token);
    setIsLoading(false);
  }, []);

  // 认证状态未确定时显示加载页
  if (isLoading) {
    return <div>加载中...</div>; // 可以替换成你自己的加载组件
  }

  // 已认证则渲染目标页面,未认证则重定向到登录页
  return isAuthenticated ? children : <Navigate to="/" />;
};

第二步:重构App.js的路由结构

把认证和未认证路由合并,用守卫组件保护需要登录才能访问的页面:

const App = () => {
  return (
    <Router>
      <Routes>
        {/* 未认证路由:登录页 */}
        <Route path="/" element={<Login />} />
        {/* 受保护的认证路由 */}
        <Route path="/dashboard" element={
          <ProtectedRoute>
            <Layout>
              <Dashboard />
            </Layout>
          </ProtectedRoute>
        } />
        <Route path="/settings" element={
          <ProtectedRoute>
            <Layout>
              <Settings />
            </Layout>
          </ProtectedRoute>
        } />
        {/* 404页面:放在所有路由最后 */}
        <Route path="*" element={<NotFound />} />
      </Routes>
    </Router>
  );
};

另外,你的Login组件里重复调用了localStorage.setItem('token'),handleLogin里已经做了这个操作,这里可以去掉,避免冗余代码。

方案二:配置服务器SPA fallback(如果使用BrowserRouter)

如果是服务器端导致的404,需要配置服务器让所有未匹配的路径返回React的index.html:

  • 若部署到Nginx,在配置文件中添加:
    location / {
      try_files $uri $uri/ /index.html;
    }
    
  • 若部署到Netlify/Vercel等平台,可在项目根目录创建_redirects文件(Netlify):
    /* /index.html 200
    

这样刷新页面时,服务器会返回React的入口文件,React Router就能正常匹配客户端路由了。

备注:内容来源于stack exchange,提问作者Zak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 12:38:04