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

Heroku部署React+Rails应用客户端路由报404问题求助

问题原因

刷新/直接访问子路由返回404是SPA应用部署的典型问题:React Router为客户端路由,路由切换在浏览器端完成,直接访问/user这类子路径时,请求会直接发送到Heroku服务端,服务端无对应路径处理规则就会返回404。
你编写的static.json不生效,核心原因是该配置仅对Heroku的create-react-app-buildpack静态托管规则生效,如果你使用Ruby on Rails托管React构建产物,Rails路由优先级高于静态文件规则,这个配置完全不会被加载。


解决方案

针对React+Ruby on Rails全栈部署的场景,优先选择Rails侧配置兜底路由的方案,稳定性最高:

方案1:Rails托管前端静态文件(全栈项目推荐)

  1. 确认React构建输出路径
    如果你使用Create React App搭建React项目,修改前端目录下的package.json,指定构建产物输出到Rails默认托管静态资源的public/build目录(如果前端代码存放在/client子目录,就修改client/package.json):
    {
      "scripts": {
        // 保留原有其他脚本,仅修改build命令指定输出路径
        "build": "BUILD_PATH=../public/build react-scripts build"
      }
    }
    
    如果前端代码不在仓库根目录,需要在仓库根目录的package.json添加脚本,确保Heroku部署时自动执行前端构建:
    {
      "scripts": {
        "postinstall": "npm run build",
        "build": "cd client && npm ci && npm run build"
      }
    }
    
  2. 开启Rails生产环境静态文件服务
    打开config/environments/production.rb,确认存在以下配置,避免环境变量缺失导致静态文件无法访问:
    config.public_file_server.enabled = true
    
  3. 添加Rails兜底路由
    打开config/routes.rb,在所有路由定义的最末尾添加以下规则,把所有非API的HTML请求转发到React入口文件,交给React Router接管路由:
    # 注意:必须放在所有其他路由的最下方,避免覆盖正常的后端接口、后台页面路由
    get '*path', to: proc { |env|
      request = Rack::Request.new(env)
      # 仅处理HTML请求,排除/api开头的后端接口路径,可根据实际接口前缀修改判断规则
      if request.format.html? && !request.path.start_with?('/api/')
        # 如果React构建产物直接输出到public根目录,删掉路径中的'build'段即可
        index_path = Rails.root.join('public', 'build', 'index.html')
        [200, { 'Content-Type' => 'text/html' }, [File.read(index_path)]]
      else
        [404, { 'Content-Type' => 'text/plain' }, ['Not Found']]
      end
    }
    
    配置完成后提交代码重新部署到Heroku即可生效。

方案2:前后端分离部署,前端用静态buildpack托管

如果你采用前后端分离架构,Rails仅提供API接口、前端通过Heroku静态buildpack托管,按以下步骤修复:

  1. 本地安装Heroku CLI后,在项目根目录执行命令配置正确的buildpack顺序:
    heroku buildpacks:clear
    heroku buildpacks:add heroku/nodejs
    heroku buildpacks:add mars/create-react-app
    heroku buildpacks:add heroku/ruby
    
  2. 修正根目录下的static.json配置,root路径必须填写相对于仓库根目录的构建产物路径(如果React项目在client子目录,就写client/build/):
    {
      "root": "build/",
      "clean_urls": true,
      "routes": {
        "/**": "index.html"
      }
    }
    

注意事项
  • 不要为了临时规避问题将BrowserRouter替换为HashRouter,该方案会让URL携带#段,影响URL美观度和SEO效果。
  • 兜底路由必须放在所有后端路由的最末尾,否则会拦截正常的接口、后台页面请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 13:39:38