部署到Heroku的React+Flask应用无法显示前端页面
我之前部署Flask+React到Heroku时也踩过几乎一模一样的坑——后端API、数据库甚至flask-admin都正常跑,但前端就是打不开,本地测试完全没问题,日志还看不出明显错误,折腾了好几个小时才搞定。给你几个最可能的排查方向:
1. 确认Flask正确配置静态文件服务
React构建后会生成build文件夹,Flask需要正确指向这个文件夹,并且处理所有非API请求返回index.html(因为React是客户端路由)。检查你的Flask主文件是不是类似这样:
import os from flask import Flask, send_from_directory # 关键:static_folder指向React的build目录,static_url_path设为空字符串 app = Flask(__name__, static_folder='client/build', static_url_path='') # 先定义所有API路由,比如你的flask-admin接口、数据库接口 @app.route('/api/status') def check_status(): return {"status": "backend running"} # 处理所有非API的请求,返回React的index.html @app.route('/', defaults={'path': ''}) @app.route('/<path:path>') def serve_react(path): # 如果请求的是静态资源(比如css、js、图片),直接返回 if path != "" and os.path.exists(os.path.join(app.static_folder, path)): return send_from_directory(app.static_folder, path) # 否则返回index.html,让React处理客户端路由 return send_from_directory(app.static_folder, 'index.html') # 必须用Heroku提供的PORT环境变量,不能硬编码 if __name__ == '__main__': app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 5000)))
2. 检查Heroku的构建脚本是否正确生成前端静态文件
Heroku需要在部署时自动构建React项目,所以你的根目录package.json里必须有heroku-postbuild脚本,确保安装前端依赖并执行build:
{ "name": "your-app-name", "scripts": { "start": "gunicorn app:app", // 启动Flask后端 "heroku-postbuild": "cd client && npm install && npm run build" // 构建React前端 }, "dependencies": { "gunicorn": "^20.1.0" // 别忘了安装gunicorn作为生产服务器 } }
另外要确认:
- 前端的
package.json在client目录下(如果你的项目结构是根目录放Flask,子目录client放React) - Heroku的node版本配置正确,可以在根目录加
.nvmrc文件指定版本,比如18.17.0,避免依赖安装失败
3. 验证React生产环境的API路径配置
本地开发时React可能访问http://localhost:5000/api,但生产环境要改成相对路径,避免跨域。在React项目的.env.production文件里设置:
REACT_APP_API_URL=/api
然后在React的API请求里用这个环境变量,比如:
fetch(`${process.env.REACT_APP_API_URL}/status`) .then(res => res.json()) .then(data => console.log(data))
4. 深挖Heroku日志的细节
虽然你说日志没明显错误,但建议用heroku logs --tail --app your-app-name实时查看日志,重点看:
heroku-postbuild阶段有没有报错,比如npm install超时、依赖缺失- Flask启动时有没有提示静态文件目录不存在(如果build失败的话会出现)
- 访问前端时的请求日志,看返回的是200还是404、500,有没有路由匹配的问题
5. 检查.gitignore是否误排除了必要文件
不要在根目录的.gitignore里排除client/node_modules(Heroku会在postbuild时重新安装),但可以排除client/build(因为Heroku会自己build)。如果之前误把client目录排除了,那Heroku根本找不到前端代码,自然无法build。
先从这几个方向查,大概率是静态文件配置或者build脚本的问题,我当时就是漏了把所有非API请求转发到index.html,导致前端路由直接返回404。
内容的提问来源于stack exchange,提问作者dizzy

