如何通过FastAPI部署带路由的React构建产物
问题:React静态资源挂载FastAPI后显示空白页面
背景情况
- 用
create-react-app创建React应用,执行npm run build生成build文件夹,路由配置如下:
function App() { return ( <> <Routes> <Route path="/" element={<Users />} /> <Route path="/doctors" element={<Doctors />} /> <Route path="/register" element={<Register />} /> <Route path="/login" element={<Register />} /> <Route path="/profile" element={<Profile />} /> <Route path="/schedules" element={<Schedules />} /> <Route path="/visits" element={<Visits />} /> </Routes> </> ) }
- 用
serve -s build可正常运行应用,但将build内容复制到FastAPI项目的static目录后,访问localhost:8000/或localhost:8000/index.html仅显示空白页面,控制台仅输出CONTENT IS RUNNING。
FastAPI项目结构
FastpAPI static/ css/ js/ index.html manifest.json ... main.py auth.py models.py ...
FastAPI配置(main.py)
app = FastAPI() app.include_router(auth.router) app.include_router(api.router) origins = [ "http://localhost:3000", "http://127.0.0.1:8000", ] app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.mount("/", StaticFiles(directory="static", html=True), name="static")
解决方案
1. 调整静态文件挂载顺序
FastAPI路由匹配从上到下执行,先挂载API路由会拦截根路径请求。把静态文件挂载放在路由引入之前:
app = FastAPI() # 先挂载静态文件 app.mount("/", StaticFiles(directory="static", html=True), name="static") # 再引入API路由 app.include_router(auth.router) app.include_router(api.router) # 跨域中间件配置保持不变 origins = [ "http://localhost:3000", "http://127.0.0.1:8000", ] app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], )
2. 配置React相对路径
在React项目的package.json中添加"homepage": ".",重新执行npm run build后,将新的build内容复制到FastAPI的static目录。这能确保生成的资源路径为相对路径,避免找不到css、js文件。
3. 检查静态资源请求状态
打开浏览器开发者工具(F12)切换到Network标签,刷新页面查看资源请求状态:
- 若返回404,确认
static目录下的文件结构与build完全一致 - 检查
index.html中资源引用路径是否为相对路径(比如./css/main.xxx.css)
4. 处理SPA路由 fallback
React是单页应用,直接访问/doctors这类子路由会返回404,需给API路由加前缀,让FastAPI将非API请求转发到index.html:
# 给API路由添加前缀 app.include_router(auth.router, prefix="/api") app.include_router(api.router, prefix="/api") # 静态文件挂载在根路径,html=True自动处理SPA fallback app.mount("/", StaticFiles(directory="static", html=True), name="static")
5. 清除浏览器缓存
按Ctrl+Shift+R强制刷新页面,或清除浏览器缓存后重新访问,避免旧资源缓存导致的问题。
内容的提问来源于stack exchange,提问作者Philip
相关产品推荐
相关产品推荐

