auto-sync: 2026-05-21 20:09:03
This commit is contained in:
+25
-2
@@ -265,9 +265,32 @@ async def list_projects_compat():
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 静态文件服务(前端 dist/,F18 实现)
|
||||
# 靜態文件服務(前端 dist/,F18 實現)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
DIST_DIR = Path(__file__).parent / "frontend" / "dist"
|
||||
if DIST_DIR.exists():
|
||||
app.mount("/", StaticFiles(directory=str(DIST_DIR), html=True), name="frontend")
|
||||
# v3.1: 緩存策略 - HTML 不緩存(確保新版本生效),JS/CSS 長緩存(Vite content hash 已處理)
|
||||
import mimetypes
|
||||
_static_app = StaticFiles(directory=str(DIST_DIR), html=True)
|
||||
|
||||
class CachedStaticFiles:
|
||||
"""包裝 StaticFiles,添加 Cache-Control 頭"""
|
||||
def __init__(self, app):
|
||||
self._app = app
|
||||
|
||||
async def __call__(self, scope, receive, send):
|
||||
original_send = send
|
||||
async def patched_send(message):
|
||||
if message.get("type") == "http.response.start":
|
||||
headers = dict(message.get("headers", []))
|
||||
path = scope.get("path", "")
|
||||
if path.endswith(".html") or path == "/":
|
||||
headers[b"cache-control"] = b"no-cache, no-store, must-revalidate"
|
||||
elif any(path.endswith(ext) for ext in (".js", ".css", ".woff2", ".png", ".ico")):
|
||||
headers[b"cache-control"] = b"public, max-age=31536000, immutable"
|
||||
message["headers"] = list(headers.items())
|
||||
await original_send(message)
|
||||
await self._app(scope, receive, patched_send)
|
||||
|
||||
app.mount("/", CachedStaticFiles(_static_app), name="frontend")
|
||||
|
||||
Reference in New Issue
Block a user