我想在 Fastapi 提供的 Web 应用程序中显示 PDF。这些文件是在 Javascript 中获取的。简化代码:
fetch('/files/', {method: "POST", body: JSON.stringify(myFilePathString),cache: "no-cache"})
.then(function(response) { return response.blob(); })
.then(function(blob) { myDomElement.src = URL.createObjectURL(blob); });
问题:浏览器总是重新加载文件,从不使用缓存文件。使用“缓存:“无缓存””,我希望浏览器验证最近加载的文件是否是最新的并获取该文件。重新加载文件时,标头中的 ETag 保持不变。显然,从 BLOB 创建的 URL 在每次重新加载时都会发生变化。据我了解,这可能是原因。无论如何,有没有办法通过这种机制使用浏览器缓存?
在客户端,您需要将请求中的
If-None-Match
标头设置为当前的ETag值。
在后端,将
If-None-Match
中传递的ETag值与文件当前的ETag值进行比较。如果它们相同,则返回 304 Not Modified 状态,没有正文。这告诉浏览器使用缓存的版本。如果它们不同,这意味着文件已更改,您需要返回新文件。
这里是 FastAPI 中实现后端部分的示例代码:
from fastapi import Body, FastAPI, Header, Response, FileResponse
from pydantic import FileUrl
app = FastAPI()
@app.get("/files/")
async def get_file(file_path: FileUrl = Body(),
if_none_match: str | None = Header(default=None)):
file_etag = get_etag(file_path)
if if_none_match == file_etag:
return Response(status_code=304)
else:
return FileResponse(file_path)
您可以用您计算 ETag 的方法替换
get_etag
函数调用。
我使用 POST 请求在 JSON 正文中传递文件路径,因为您在 Javascript 示例中这样做了。但是,我认为最好使用将文件路径作为路径参数传递的 GET 请求。您可以在 FastAPI 教程
中了解如何执行此操作