首先,您需要在服务器端调整您的端点以接受path 参数,如当前定义的那样,lat 和long 预计为query 参数;但是,在您的 javascript 代码中,您尝试将这些坐标作为 path 参数发送。因此,您的端点应如下所示:
@app.get("/{lat}/{long}/")
async def read_item(lat: float, long: float):
接下来,在FileResponse 中设置filename,这样它就可以包含在响应Content-Disposition 标头中,以后可以在客户端检索:
return FileResponse("/tmp/myics.ics", filename="myics.ics")
如果您正在执行cross-domain 请求(另请参阅FastAPI CORS),请确保将Access-Control-Expose-Headers:Content-Disposition 添加到服务器端的响应标头(以公开Content-Disposition 标头),否则filename 获胜'不能在客户端访问:
headers = {'Access-Control-Expose-Headers': 'Content-Disposition'}
return FileResponse("/tmp/myics.ics", filename="myics.ics", headers=headers)
在客户端,您可以使用与this answer 类似的方法(该答案建议的downloadjs 库现在已过时;因此,我不建议使用它)。下面的示例还考虑了 filename 包含 unicode 字符(即 -, !, (, ) 等)并因此以 filename*=utf-8''Na%C3%AFve%20file.txt 的形式出现(utf-8 编码)的情况(参见 @ 987654329@了解更多详情)。在这种情况下,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, otherwise it won't work in Firefox
a.click();
a.remove(); // afterwards, remove the element
});