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

如何使用Hapi部署带React-Router的React-JS应用?重定向疑问

解决React Router + Hapi部署的SPA路由问题

没错,你确实需要配置Hapi将所有客户端路由(比如/user/:id)转发到build/index.html —— 这是因为你用Create React App打包后的项目是单页应用(SPA),所有路由逻辑都是在浏览器端由React Router处理的,服务器本身并不知道这些自定义路由。

为什么要这么做?

当你直接在浏览器访问/user/123时,Hapi服务器会默认去寻找对应的物理文件(比如build/user/123.html),但显然这个文件不存在,就会返回404错误。而把这些请求转发到index.html后,React Router就能接管请求,在客户端解析路由并渲染对应的组件,同时保留组件状态。

具体实现步骤

首先确保你已经安装了@hapi/inert插件(用来处理静态文件),然后按以下方式配置Hapi:

  1. 注册inert插件
const Hapi = require('@hapi/hapi');
const Inert = require('@hapi/inert');
const path = require('path');

const init = async () => {
  const server = Hapi.server({
    port: process.env.PORT || 3000,
    host: '0.0.0.0' // 允许EC2外部访问
  });

  // 注册inert插件
  await server.register(Inert);
  1. 配置静态资源路由
    先让Hapi正确处理build/目录下的静态文件(比如CSS、JS、图片等):
// 服务build目录下的静态资源
  server.route({
    method: 'GET',
    path: '/{param*}',
    handler: {
      directory: {
        path: path.join(__dirname, 'build'),
        redirectToSlash: true,
        index: true
      }
    }
  });
  1. 添加Catch-All路由处理客户端路由
    注意:这个路由要放在静态资源路由之后!它会捕获所有未被静态资源或API路由匹配的请求,返回index.html:
// 捕获所有客户端路由,返回index.html
  server.route({
    method: 'GET',
    path: '/{any*}',
    handler: (request, h) => {
      return h.file(path.join(__dirname, 'build', 'index.html'));
    }
  });

  await server.start();
  console.log('Server running on %s', server.info.uri);
};

process.on('unhandledRejection', (err) => {
  console.log(err);
  process.exit(1);
});

init();

重要提醒

如果你有后端API路由(比如/api/users),一定要把这些API路由放在Catch-All路由之前,这样Hapi会优先处理API请求,不会把API请求也转发到index.html。

这样配置后,无论是访问/home还是/user/123,服务器都会返回index.html,React Router就能正常解析路由并渲染对应的组件,同时不会丢失组件状态啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:27:18