javascript - 如何在前端使用 JavaScript Fetch API 从 FastAPI 后端下载文件?

标签 javascript python html fetch-api fastapi

这是我的 FastAPI(python) 代码,它返回一个 .ics 文件:

@app.get("/latLong/")
async def read_item(lat: float,long:float):
    mainFunc(lat,long)
    return FileResponse("/tmp/myics.ics")

这是我使用 Fetch API 编写的前端代码:

<script>
  async function apiCall(long,lat) {
    let myObject = await fetch('myapi.com/lat/long');
    let myText = await myObject.text();
  }
</script>

因此,从我的 visor(我的 api 日志)中,它成功调用了 API。但从前端,我试图让它返回文件。

我想要实现的最终结果是,当用户单击按钮时,浏览器抓取位置,然后将位置发送到 API,API 返回用户可以下载的文件。

最佳答案

首先,您需要调整服务器端的端点以接受 path参数,按照当前定义的方式,latlong 预计为 query参数代替;但是,在您提供的 JavaScript 代码中,您似乎正在尝试将这些坐标作为 path 参数发送。因此,您的端点应如下所示:

@app.get("/{lat}/{long}/")
async def read_item(lat: float, long: float):

接下来,在 FileResponse 中设置文件名 ,这样它就可以包含在 Content-Disposition 中响应 header ,稍后可以在客户端检索:

return FileResponse("/tmp/myics.ics", filename="myics.ics")

如果您正在执行cross-origin请求(另请参阅 FastAPI CORS),请确保设置 Access-Control-Expose-Headers服务器端的响应头,指示 Content-Disposition 头应该可供浏览器中运行的 JS 脚本使用;否则,客户端将无法访问文件名。示例:

headers = {'Access-Control-Expose-Headers': 'Content-Disposition'}
return FileResponse("/tmp/myics.ics", filename="myics.ics", headers=headers)

在客户端,您可以使用类似的方法 this answerthis answer 。下面的示例还考虑了 filename 包含 unicode 字符(即 -、!、(、) 等)的情况,因此出现 (utf-8编码),例如 filename*=utf-8''Na%C3%AFve%20file.txt 的形式(有关更多详细信息,请参阅 here)。在这种情况下,decodeURIComponent()函数用于解码文件名。下面的工作示例:

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  
    });

关于javascript - 如何在前端使用 JavaScript Fetch API 从 FastAPI 后端下载文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71191662/

相关文章:

javascript - CSS 表格和父 div 不遵循它们的高度和宽度属性? Jquery可调整大小

javascript - jQuery - 获取最高图像的高度,将其他图像的高度差应用于上边距

python - 无法将 Pandas pct_change 与日期一起使用

php - HTML\PHP : Flash Player detection technique

javascript - 在 JavaScript 中检查整数

javascript - 如何使用单选按钮重定向到下一页而不使用提交按钮?

python如何获取枚举的名称

python - 如何输入传递给 numpy.asarray 的变量以生成 2D float 组?

javascript - 从 map 中选择表行。 Angular/Google map 集成

html - FileUploader 接受 ="image/*"验证问题