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

React Router v5 生产环境嵌套路由失效问题排查

HashRouter转BrowserRouter后生产环境Nginx 404问题

问题描述

近期将项目中的HashRouter替换为BrowserRouter,开发环境通过在webpack.dev.config添加以下配置可正常运行:

devServer: {
  historyApiFallback: true,
  allowedHosts: 'all',
},

但生产环境中:

  • 访问myapp.com可正常加载
  • 访问myapp.com/home或myapp.com/intro时返回Nginx 404错误
  • 访问myapp.com/#/home会自动重定向到myapp.com/home且页面可正常渲染(已配置兼容旧hash路径的全局转换逻辑)

现有Webpack配置

webpack.common.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: path.join(__dirname, 'src', 'index.js'),
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
    chunkFilename: '[id].js',
    publicPath: '/',
    hashFunction: 'xxhash64',
  },
  resolve: {
    extensions: ['.js', '.jsx'],
  },
  module: {
    rules: [
      {
        test: /\.(scss)$/,
        use: [
          { loader: 'style-loader' },
          { loader: 'css-loader' },
          {
            loader: 'postcss-loader',
            options: {
              postcssOptions: {
                plugins: function () {
                  return [require('autoprefixer')]
                },
              },
            },
          },
          { loader: 'sass-loader' },
        ],
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env', '@babel/preset-react'],
          },
        },
      },
      {
        test: /\.css$/,
        exclude: /node_modules/,
        use: [
          { loader: 'style-loader' },
          {
            loader: 'css-loader',
            options: {
              modules: {
                localIdentName: '[name]__[local]___[hash:base64:5]',
              },
              sourceMap: true,
            },
          },
          {
            loader: 'postcss-loader',
            options: {
              postcssOptions: {
                plugins: [['autoprefixer', {}]],
              },
            },
          },
        ],
      },
      {
        test: /\.(png|jpe?g|gif|svg)$/,
        use: [
          {
            loader: 'url-loader',
            options: { limit: 10000, name: 'static/media/[name].[hash:8].[ext]' },
          },
        ],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: __dirname + '/public/index.html',
      filename: 'index.html',
      inject: 'body',
      favicon: './public/favicon.ico',
      manifest: './public/manifest.json',
    }),
  ],
}

webpack.prod.js

const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
const Dotenv = require('dotenv-webpack');

module.exports = merge(common, {
  mode: 'production',
  performance: {
    hints: false,
    maxEntrypointSize: 512000,
    maxAssetSize: 512000,
  },
  plugins: [
    new Dotenv({
      path: './.env',
    }),
  ],
})

解决方案

问题出在Nginx未配置路由 fallback,开发环境的historyApiFallback: true会把所有路由请求转发到index.html,但生产环境需要在Nginx中做相同配置。

修改Nginx的站点配置文件(通常位于/etc/nginx/sites-available/或/etc/nginx/conf.d/目录下),添加try_files指令:

server {
  listen 80;
  server_name myapp.com;
  root /path/to/your/project/dist; # 替换为实际的dist目录绝对路径

  location / {
    # 优先尝试访问请求的文件/目录,找不到则返回index.html
    try_files $uri $uri/ /index.html;
  }
}

配置完成后,重启Nginx生效:

sudo systemctl restart nginx

说明

BrowserRouter依赖前端路由接管,当用户直接访问myapp.com/home时,Nginx会尝试寻找服务器上的home文件或目录,找不到就返回404。添加try_files后,所有找不到的资源请求都会转发到index.html,由React应用处理路由逻辑,就能正常渲染对应页面了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 19:27:45