Jof*_*yab 8 reactjs react-fullstack fastapi
我尝试将前端安装到/with app.mount,但这会使我的所有/api路由无效。我还尝试了以下代码将文件夹安装到/static各自的路由中并index.html在以下位置提供文件/:
@app.get("/")
def index():
project_path = Path(__file__).parent.resolve()
frontend_root = project_path / "client/build"
return FileResponse(str(frontend_root) + '/index.html', media_type='text/html')
static_root = project_path / "client/build/static"
app.mount("/static", StaticFiles(directory=static_root), name="static")
Run Code Online (Sandbox Code Playgroud)
这大部分有效,但client/build文件夹中包含的文件未安装,因此无法访问。我知道 Node.js 有一种通过相对路径为前端页面提供服务的方法res.sendFile("index.html", { root: </path/to/static/folder });。FastAPI 中是否有等效的函数可以执行此操作?
Ric*_*rdo 18
clmno的解决方案是两台服务器+路由。Jay Jay Cayabyab正在 API 上寻找一个端点,为 Webpacked SPA 提供服务,就是您想要的那种npm run build。我一直在寻找完全相同的解决方案,因为这就是我正在使用 Flask 所做的事情,并且我正在尝试用 FastAPI 替换 Flask。
FastAPI 的文档中多次提到它是基于 starlette 的。在 starlette 上搜索提供 SPA 服务时,我发现了这个问题的回复。当然,这对我来说并不是现成的,因为我错过了一些在建议的解决方案中未提及的导入内容。
这是我的代码,它正在工作:
from fastapi.staticfiles import StaticFiles
class SPAStaticFiles(StaticFiles):
async def get_response(self, path: str, scope):
response = await super().get_response(path, scope)
if response.status_code == 404:
response = await super().get_response('.', scope)
return response
app.mount('/my-spa/', SPAStaticFiles(directory='folder', html=True), name='whatever')
Run Code Online (Sandbox Code Playgroud)
注意:我故意更改了端点(my-spa)、目录(文件夹)和应用程序名称(无论什么)的名称,以强调这些不必完全相同。
在本例中,您将构建的 SPA 放入该folder文件夹中。为此,请在 SPA 项目文件夹中运行npm run build或yarn run build,然后您会得到一个名为 的文件夹dist。将所有文件和文件夹复制dist到此folder文件夹中。
完成此操作后,运行 FastAPI 应用程序,然后转到http://localhost:5000/my-spa/. 为了绝对清楚起见,我使用这个特定 URL 的原因是我的应用程序有一个像这样的 main:
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=5000)
Run Code Online (Sandbox Code Playgroud)
所以它从端口 5000 开始。您的情况可能有所不同。
我讨厌这些回复中缺少导入,因为有时回复似乎从未运行过。当我输入此内容时,我的程序正在另一个屏幕上运行,因此这不会浪费您的时间。然而,假设你已经在做这些微不足道的事情,我自己可能会错过一些重要的事情
from fastapi import FastAPI
Run Code Online (Sandbox Code Playgroud)
等等。如果您尝试此操作并发现缺少任何内容,请在这里告诉我。
更新里卡多的答案,
在某个时候starlette.staticfiles.StaticFiles开始引发HTTPException而不是 PlaintText 404 响应,因此对于托管 SPA,我想新版本的代码应该如下所示:
from fastapi import HTTPException
from starlette.exceptions import HTTPException as StarletteHTTPException
# ...
class SPAStaticFiles(StaticFiles):
async def get_response(self, path: str, scope):
try:
return await super().get_response(path, scope)
except (HTTPException, StarletteHTTPException) as ex:
if ex.status_code == 404:
return await super().get_response("index.html", scope)
else:
raise ex
app.mount("/", SPAStaticFiles(directory="dist", html=True), name="spa-static-files")
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9152 次 |
| 最近记录: |