我在 FastAPI 中渲染 HTMl 文件时遇到问题。
main.py文件
static_dir = os.path.join(os.path.dirname(__file__), "static") app.mount("/",StaticFiles(directory=static_dir, html=True),name="static") @app.get("/") async def index(): return FileResponse('index.html', media_type='text/html')
使用 uvicorn 运行上述文件时,我能够渲染 http://127.0.0.1:8765/ 处的 HTML 文件,但静态文件(例如 css、js 和图像)不会被渲染。
index.html:HTML 文件的一些代码(由 Angular JS 构建)
<link rel="stylesheet" href="styles.87afad25367d1df4.css" media="print" onload="this.media='all'"><noscript> <link rel="stylesheet" href="styles.87afad25367d1df4.css"></noscript></head> <body class="cui"> test <app-root></app-root> <script src="runtime.7f95ee6540776f88.js" type="module"></script> <script src="polyfills.a246e584d5c017d7.js" type="module"></script> <script src="main.4f51d0f81827a3db.js" type="module"></script> </body></html>
文件结构:
modulename - static - index.html - styles.87afad25367d1df4.css - runtime.7f95ee6540776f88.js - polyfills.a246e584d5c017d7.js - main.4f51d0f81827a3db.js - main.py - __init__.py
当我打开浏览器控制台时,它显示如下:
CSS/js 应该在不包含静态的情况下进行渲染,例如http://127.0.0.1:8765/styles.87afad25367d1df4.css 但它在从 http://127.0.0.1:8765/static/styles.87afad25367d1df4.css 加载的浏览器上运行。
我不确定如何解决这个问题,我们将不胜感激。
更新:添加以下代码以更好地解释
main.py
import uvicorn import os import webbrowser from fastapi import FastAPI from fastapi.responses import FileResponse from fastapi.staticfiles import StaticFiles from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import HTMLResponse app = FastAPI( title="UI", description="This is to test", ) app.add_middleware( CORSMiddleware, allow_origins=['*'], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) static_dir = os.path.join(os.path.dirname(__file__), "static") app.mount("/",StaticFiles(directory=static_dir, html=True),name="static") def start_server(): # print('Starting Server...') uvicorn.run( "ui.main:app", host="0.0.0.0", port=8765, log_level="debug", reload=True, ) # webbrowser.open("http://127.0.0.1:8765/") if __name__ == "__main__": start_server()
将此文件作为 test.py 文件中的包/模块运行:
from ui import main if __name__ == "__main__": main.start_server()
index.html:
<!DOCTYPE html><html lang="en"> <head> <meta charset="utf-8"> <title>WingmanUi</title> <base href="static/"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" type="image/x-icon" href="favicon.ico"> <link rel="stylesheet" href="styles.87afad25367d1df4.css" media="print" onload="this.media='all'"> </head> <body> This is to test <script src="runtime.7f95ee6540776f88.js" type="module"></script> <script src="polyfills.a246e584d5c017d7.js" type="module"></script> <script src="main.4f51d0f81827a3db.js" type="module"></script> </body> </html>
文件结构:
ui - static - index.html - styles.87afad25367d1df4.css - runtime.7f95ee6540776f88.js - polyfills.a246e584d5c017d7.js - main.4f51d0f81827a3db.js - main.py - __init__.py
P粉0290579282023-12-12 16:29:07
首先,当使用 StaticFiles
时html
标志设置为 True
,以便提供静态文件(对于动态网页,请参阅 模板 代替),例如:
from fastapi import FastAPI from fastapi.staticfiles import StaticFiles app = FastAPI() app.mount('/static', StaticFiles(directory='static', html=True), name='static')
您不必定义端点来服务索引页,因为 html=True
意味着在 HTML 模式下运行您的应用程序;因此,FastAPI/Starlette 会自动加载 index.html
— 请参阅 Starlette 文档 静态文件
。另外,如果您需要其他端点,请注意应用程序中定义端点的顺序很重要。。 p>
其次,由于您已安装 StaticFiles
实例并指定 directory='static'
,因此您的静态文件预计将从该目录提供。因此,您所要做的就是将所有静态文件以及 HTML 文件移动到 static
目录中。然后,您应该能够按如下方式提供静态文件(假定您已将 StaticFiles
实例安装到 /
,例如 app.mount('/', ...
):
<script src="someScript.js"></script>
或者,如果 StaticFiles
实例安装到 /static
,例如 app.mount('/static', ...)
(另请参阅此答案):
<script src="static/someScript.js"></script>
就您而言,由于您已将 StaticFiles
实例安装到 /
,因此静态文件仍以 static
前缀加载的原因,例如 http://127.0.0.1:8000/static/someScript.js
只是因为您添加了
HTML 文档中用于所有相对 URL 的 URL 。因此,您应该从 HTML 文件中删除以下行:
<base href="static/">