Abb*_*bas 4 python static-files starlette fastapi fileresponse
这是一个简单的静态 FastAPI 应用程序。通过此设置,即使根路径预计返回 a FileResponse,custom.html应用程序仍会返回index.html。如何让根路径工作并渲染custom.html?
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
app = FastAPI()
app.mount(
"/",
StaticFiles(directory="static", html=True),
name="static",
)
@app.get("/")
async def index() -> FileResponse:
return FileResponse("custom.html", media_type="html")
Run Code Online (Sandbox Code Playgroud)
根据 Starlette文档:
\n\n\n静态文件
\n签名:
\nStaticFiles(directory=None, packages=None, check_dir=True)\n
\n- \n
html- 以 HTML 模式运行。index.html如果此类文件存在,则自动加载目录。
另外,如您提供的代码片段所示,您已挂载StaticFiles到根目录(即/),而不是例如/static(或其他路径名),如下所示:
from fastapi import FastAPI\nfrom fastapi.staticfiles import StaticFiles\n\napp = FastAPI()\n\napp.mount(\'/static\', StaticFiles(directory=\'static\'), name=\'static\')\nRun Code Online (Sandbox Code Playgroud)\n根据 FastAPI文档:
\n\n\n“安装”意味着在特定路径中添加完整的“独立”应用程序,然后负责处理所有子路径。
\n
因此,任何以 开头的路径都/将由该应用程序处理StaticFiles,并且由于html=True在参数中指定,因此index.html将自动加载;无论创建一个指向根路径的单独端点/并尝试返回其他内容,如问题中给出的示例所示。
例如,如果您在定义端点后app.mount("/",StaticFiles(...移动了行,您会发现顺序很重要,并且不会再自动加载,因为端点是按 order 评估的。请注意,在您的情况下,您可能会得到一个,因为您的端点将被调用并尝试查找,但如果该文件不是位于根目录下,而是位于目录下(如代码所示),那么您将出现错误,因此您应该返回.@app.get("/")index.htmlInternal Server Error@app.get("/")custom.html//staticFile does not existFileResponse(\'static/custom.html\')
即使您删除了html=True,但保留StaticFiles安装到根目录并在端点之前定义,您在尝试访问 时/也会收到错误响应。这是因为路由仍然由应用程序处理(如前所述),因此您应该需要指定您想要访问的文件(当不使用时),例如. 即使您在代码中定义了其他端点(例如,,,),只要挂载到根目录(即,)并在代码中定义在所有其他端点之前,例如:{"detail":"Not Found"}http://localhost:8000//StaticFileshtml=Truehttp://localhost:8000/index.html/register/login/helloStaticFiles/
app.mount(\'/\', StaticFiles(directory=\'static\'), name=\'static\')\n\n@app.post(\'/register\')\nasync def register():\n pass\n\n@app.post(\'/login\')\nasync def login():\n pass\n\n@app.get(\'/hello\')\nasync def hello():\n pass\nRun Code Online (Sandbox Code Playgroud)\n对这些路由的每个请求都将再次由应用程序处理StaticFiles,因此会导致错误响应,例如{"detail":"Not Found"}(如果您发送GET请求,例如当您在浏览器的地址栏中键入 URL,然后点击Enter键,并且给定路径与 Web 目录中的文件名不匹配static),或者{detail": "Method Not Allowed"}(如果您POST通过 Swagger UI 或某些其他客户端平台/应用程序发出请求)。正如Starlette 的文档StaticFiles中所述(另请参阅StaticFiles类实现):
\n\n静态文件将响应
\n404 Not found或响应不匹配405 Method not allowed的请求。在 HTML 模式下,如果\n404.html存在,则会显示 404 响应。
因此,您应该将StaticFiles实例安装到不同/唯一的路径,例如/static(即,app.mount(\'/static\', ...如本答案顶部所示),或者,如果您仍然希望将StaticFiles实例安装到/路径,请StaticFiles 在之后定义在声明所有 API进行定义端点,例如:
from fastapi import FastAPI\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.responses import FileResponse\n\napp = FastAPI()\n\n\n@app.post(\'/register\')\nasync def register():\n pass\n\n\n@app.post(\'/login\')\nasync def login():\n pass\n\n\n@app.get(\'/hello\')\nasync def hello():\n pass\n\n\n@app.get(\'/\')\nasync def index():\n return FileResponse(\'static/custom.html\')\n \n \napp.mount(\'/\',StaticFiles(directory=\'static\', html=True), name=\'static\')\nRun Code Online (Sandbox Code Playgroud)\n每次加载网页时,浏览器都会缓存页面上的大部分内容,以缩短加载时间(用户下次加载页面时)。因此,如果您尝试了前面提供的示例,即应用程序在每个 API 端点之前StaticFiles定义,然后使用相同的浏览器会话,您尝试了上面的示例,其中应用程序在所有 API 端点之后定义,但浏览器在浏览器中访问\xe2\x80\x94时,仍然显示文件内容而不是\xe2\x80\x94,这是由于浏览器从缓存加载网页所致。为了解决这个问题,您可以清除浏览器的缓存,或者在隐身窗口中打开网页(完成后将其关闭),或者只需在浏览器中按+而不是仅按(使用隐身或常规窗口),这将强制浏览器从服务器检索网页,而不是从缓存加载网页。StaticFilesstatic/index.htmlstatic/custom.htmlhttp://localhost:8000/CtrlF5F5
关于 FastAPI 中端点的顺序,您可能还会发现这个答案很有帮助。
\nhtml=Truehtml将实例参数设置StaticFiles为True(即html=True)只是提供了一种仅用一行代码即可提供 Web 内容目录的简单方法。如果您只需要提供静态文件,例如包文档目录,那么这就是正确的方法。但是,如果您需要提供动态更新的不同 HTML 文件,并且希望创建其他路由/端点,那么您最好看看Templates(而不是 FileResponse),以及将StaticFiles实例挂载到不同的路径(例如,/static),而不是根路径(并且不使用html=True)。
| 归档时间: |
|
| 查看次数: |
3685 次 |
| 最近记录: |