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

React项目中react-router-dom页面刷新报404错误的解决方法

React应用刷新时出现404错误(GET /employees 404)

问题描述

登录后跳转至带导航栏的Root页面,点击导航链接(如/employees)页面正常显示,但刷新浏览器时抛出错误:GET http://localhost:8080/employees 404 (Not Found)。使用react-router-dom的BrowserRouter时出现该问题,换成HashRouter后刷新正常但URL会带#,不符合需求。

相关路由配置代码如下:

index.js

import { BrowserRouter as Router, Routes, Route } from "react-router-dom";

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <Router>
        <Routes>
          <Route path="/*" element={<App />} />
        </Routes>
      </Router>
    </Provider>
  </React.StrictMode>,
  document.getElementById("app")
);

App.jsx

function App() {
  const isLoggedIn = useSelector((state) => state.auth.isLoggedIn);
  const dispatch = useDispatch();
  const navigate = useNavigate();

  // 处理登录
  const handleLogin = () => {
    dispatch(login());
  };

  // 处理登出
  const handleLogout = () => {
    dispatch(logout());
    navigate("/", { replace: true });
  };

  // 刷新页面时校验token有效性
  useEffect(() => {
    const refresh_token = localStorage.getItem("refresh_token");

    if (!refresh_token) {
      navigate("/");
      return;
    }
    axiosInstance
      .get("/auth/refresh", {
        headers: {
          Authorization: `Bearer ${refresh_token}`,
        },
      })
      .then(() => {
        dispatch(login());
      })
      .catch((error) => {
        navigate("/login");
        localStorage.clear();
        return Promise.reject(error);
      });
  }, [dispatch, navigate]);

  return (
    <Routes>
      <Route path="/" element={<Login onLogin={handleLogin} />} />
      {isLoggedIn ? (
        <Route path="/" element={<Root onLogout={handleLogout} />}>
          <Route index element={<Topics />} />
          <Route path="employees" element={<EmployeeList />} />
          <Route path="employees/create" element={<RegisterEmployee />} />
          <Route path="register" element={<Register />} />
          <Route path="dashboard" element={<Dashboard />} />
        </Route>
      ) : null}
    </Routes>
  );
}

export default App;

原因分析

BrowserRouter依赖HTML5 History API实现无#的URL。点击导航链接时,react-router-dom是在客户端完成路由跳转,不会向服务器发送请求;但刷新页面时,浏览器会直接向服务器请求当前URL(比如/employees),而你的服务器没有配置对应路径的路由,因此返回404。

解决方案

1. 开发环境配置(以Create React App为例)

在项目根目录创建setupProxy.js文件,添加以下代码:

const { createProxyMiddleware } = require('http-proxy-middleware');
const path = require('path');

module.exports = function(app) {
  // 代理API请求到后端服务器(替换为你的实际API前缀和后端地址)
  app.use(
    '/api',
    createProxyMiddleware({
      target: 'http://localhost:3000',
      changeOrigin: true,
    })
  );

  // 所有非API请求都返回index.html,交给客户端路由处理
  app.get('*', (req, res) => {
    res.sendFile(path.resolve(__dirname, 'public', 'index.html'));
  });
};

2. 生产环境配置

根据服务器类型做对应配置:

  • Nginx:在Nginx配置文件中添加try_files指令,将所有请求指向index.html
server {
  listen 80;
  server_name your-domain.com;
  root /path/to/your/react/app/build;
  index index.html;

  location / {
    try_files $uri $uri/ /index.html;
  }

  # 代理API请求到后端
  location /api {
    proxy_pass http://localhost:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
  }
}
  • Express服务器:添加中间件处理所有路由,返回index.html
const express = require('express');
const path = require('path');
const app = express();

// 托管React构建后的静态文件
app.use(express.static(path.join(__dirname, 'build')));

// 所有路由请求都返回index.html
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'build', 'index.html'));
});

app.listen(8080, () => {
  console.log('Server running on port 8080');
});

3. 代码层面优化

确保axiosInstance配置了正确的baseURL,避免把前端路由误当作API请求:

const axiosInstance = axios.create({
  baseURL: '/api', // 替换为你的API前缀
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 00:23:19