我有一个 React 应用,我正尝试通过 FastAPI 静态提供该应用。我的文件夹中有我所有的 React 构建工件static
。因此,我的 FastAPI 应用如下所示:
static/
assets/
index-lATvXaZG.js
index.html
app.py
在app.py中,我有:
app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="react")
@app.get("")
@app.get("/")
@app.get("/index.html")
def serve_index():
return FileResponse("static/index.html")
但是,当index.html
加载时,客户端理所当然地会对 发出 GET 请求/assets/index-lATvXaZG.js
。当然,FastAPI 找不到它。
我可以在我的 React 应用程序中(或者,在我的 FastAPI 设置中)进行设置以使路径对齐吗?
我首先强烈建议看一下这个答案和这个答案,因为这里发布的答案基本上是基于这些答案中所描述的内容。
选项 1
只需正确使用实例即可轻松解决此问题
StaticFiles
。这意味着您应该将html
标志设置为True
并在路由处提供静态文件/
。这样,您index.html
只需在浏览器的地址栏中输入即可访问,例如http://127.0.0.1:8000/
或http://localhost:8000/
。因此,对 的任何引用都/assets/whatever
应该可以正常工作。例子
保持文件结构原样:
选项 2
如果您想保留当前的实现(我不推荐) - 意味着您将
StaticFiles
实例挂载到/static
路径,app.mount("/static", StaticFiles(directory="static"), name="static")
即将html
标志设置为False
(这是默认设置) - 您只需在目录中的每个 HTML 文件的顶部添加以下行static
,即:这样,前缀
static/
应该自动添加到 HTML 文件内部的任何引用中,并解决问题(引用static/
开头缺少的本质上是找不到的原因assets
,因为您在/static
路线下为它们提供服务——app.mount("/static",...
)。选项 3
或者,如果您不想添加
<base href="static/">
到每个文件,您可以有一个自定义的404
exception_handler
,如此处所示,并在其内部从对象获取 URL 路径Request
,如此处所示,然后附加static/
到路径的前面并返回FileResponse
(如果文件存在)。示例:除了使用自定义的
404
exception_handler
,我们还可以使用端点来提供此类资产文件(类似于此),方法是捕获 URL 路径(如此处所述)并将其附加static/assets/
到其前面。因此,位于assets/
目录下的任何文件(例如assets/index.js
或assets/images/img.png
)都将成功提供。再次强调,我并不建议采用这种方法,使用时应非常小心,因为有人可能会恶意地利用它并尝试访问他们无权访问的可能受限制的文件 - 这就是为什么
os.path.join('static/', ...
在上面的例子中使用,以减轻这种风险,只查找static/
目录下的文件。对于此类目的,选择前面描述的选项 1应该是首选方法。
构建 React 应用程序时,在 package.json 中指定主页或在构建期间设置 PUBLIC_URL:
“主页”:“/static” npm 运行构建
app.mount(“/static”,StaticFiles(directory="static", html=True),name="static")
@app.get("/") def serve_index():`在此处输入代码在此处输入代码 return FileResponse("static/index.html")
这应该可以正确提供 index.html 和 /static 下的静态资产。尝试一下,如果遇到任何问题请告诉我。