如何在FastAPI中正确路由SvelteKit静态子页面?
解决SvelteKit静态部署在FastAPI下子页面刷新404问题
问题原因
用SvelteKit的adapter-static构建的是单页应用(SPA),前端路由由浏览器端处理。当直接输入子页面URL或刷新时,浏览器会向FastAPI发送对应路径的请求,但FastAPI的StaticFiles组件仅返回目录中存在的物理文件——而SPA模式下只有index.html是入口文件,子页面没有对应的物理文件,因此FastAPI返回404。
解决方案
需要让FastAPI将所有非API的请求转发到index.html,交由SvelteKit的客户端路由处理,具体步骤如下:
1. 调整FastAPI路由配置
修改FastAPI代码,在所有路由的最后添加通配符路由,捕获未匹配的GET请求并返回index.html:
from fastapi import FastAPI, Request from fastapi.staticfiles import StaticFiles from fastapi.responses import FileResponse import os app = FastAPI() api = FastAPI(root_path="/api") # 先挂载API,确保API请求不被后续路由拦截 app.mount("/api", api) # 定义静态文件目录路径 static_build_dir = "./webapp/build/" # 挂载静态资源,处理已存在的文件(如JS、CSS、图片等) app.mount('/', StaticFiles(directory=static_build_dir, html=True), name="webapp") # 捕获所有非API的GET请求,返回index.html作为SPA回退页 @app.get("/{full_path:path}") async def serve_spa_fallback(full_path: str): index_file_path = os.path.join(static_build_dir, "index.html") return FileResponse(index_file_path) # 你的API端点示例 @api.post("/something") async def do_something(request: Request): body = await request.json() result = do_something_fancy(body) return {"result": result}
2. 配置SvelteKit的adapter-static
确保svelte.config.js中正确设置回退页面,让adapter-static生成支持SPA路由的静态文件:
import adapter from '@sveltejs/adapter-static'; export default { kit: { adapter: adapter({ pages: 'build', assets: 'build', fallback: 'index.html' // 指定SPA回退页面,关键配置 }) } };
注意事项
- 路由顺序:API挂载和静态资源挂载必须放在通配符路由之前,否则API请求会被通配符路由拦截。
- 路径正确性:确保
static_build_dir指向SvelteKit构建后的实际目录(默认是build)。 - Websocket端点:通配符路由仅处理GET请求,你的Websocket端点不受影响,可正常访问。
内容的提问来源于stack exchange,提问作者tdpu
相关产品推荐
相关产品推荐

