首先,您需要调整服务器端的端点以接受path https://fastapi.tiangolo.com/tutorial/path-params/参数,按照当前定义的方式,lat
and long
预计将是query https://fastapi.tiangolo.com/tutorial/query-params/参数代替;但是,在您提供的 JavaScript 代码中,您似乎正在尝试将这些坐标发送为path
参数。因此,您的端点应该如下所示:
@app.get("/{lat}/{long}/")
async def read_item(lat: float, long: float):
接下来,设置filename
in FileResponse https://fastapi.tiangolo.com/advanced/custom-response/#fileresponse,这样它就可以包含在Content-Disposition https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition响应标头,稍后可以在客户端检索:
return FileResponse("/tmp/myics.ics", filename="myics.ics")
如果你正在做一个跨域 https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS请求(参见FastAPI CORS https://fastapi.tiangolo.com/tutorial/cors/以及),请确保设置Access-Control-Expose-Headers https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#access-control-expose-headers服务器端的响应头,表明Content-Disposition
header 应该可供浏览器中运行的 JS 脚本使用;否则,filename
将无法在客户端访问。例子:
headers = {'Access-Control-Expose-Headers': 'Content-Disposition'}
return FileResponse("/tmp/myics.ics", filename="myics.ics", headers=headers)
在客户端,您可以使用类似的方法这个答案 https://stackoverflow.com/a/73240097/17865804 or 这个答案 https://stackoverflow.com/a/73414443/17865804。下面的示例还考虑了以下场景:filename
包括 unicode 字符(即-, !, (, )
等),因此,以(utf-8 编码)的形式出现,例如,filename*=utf-8''Na%C3%AFve%20file.txt
(see here https://stackoverflow.com/questions/93551/how-to-encode-the-filename-parameter-of-content-disposition-header-in-http更多细节)。在这种情况下,decodeURIComponent() https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent函数用于解码filename
。下面的工作示例:
const url ='http://127.0.0.1:8000/41.64007/-47.285156'
fetch(url)
.then(res => {
const disposition = res.headers.get('Content-Disposition');
filename = disposition.split(/;(.+)/)[1].split(/=(.+)/)[1];
if (filename.toLowerCase().startsWith("utf-8''"))
filename = decodeURIComponent(filename.replace("utf-8''", ''));
else
filename = filename.replace(/['"]/g, '');
return res.blob();
})
.then(blob => {
var url = window.URL.createObjectURL(blob);
var a = document.createElement('a');
a.href = url;
a.download = filename;
document.body.appendChild(a); // append the element to the dom
a.click();
a.remove(); // afterwards, remove the element
});