![](/img/trans.png)
[英]Cannot Upload File to FastAPI backend using Fetch API in the frontend
[英]How do I download a file returned from FastAPI backend using Fetch API at the frontend?
這是我的 FastAPI(python) 代碼,它返回一個.ics
文件:
@app.get("/latLong/")
async def read_item(lat: float,long:float):
mainFunc(lat,long)
return FileResponse("/tmp/myics.ics")
這是我在 Javascript 中使用 Fetch API 的前端代碼:
<script>
async function apiCall(long,lat) {
let myObject = await fetch('myapi.com/lat/long');
let myText = await myObject.text();
}
</script>
所以從我的遮陽板(我的 api 日志)中,它成功地調用了 API。 但從前端,我試圖讓它返回文件。
我想要實現的最終結果是當用戶單擊按鈕時,瀏覽器抓取位置,然后將位置發送給 API,API 返回一個用戶可以下載的文件。
首先,您需要在服務器端調整您的端點以接受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")
如果您正在執行跨域請求(另請參閱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)
在客戶端,您可以對這個答案使用類似的方法(該答案建議的downloadjs庫現在已過時;因此,我不建議使用它)。 下面的示例還考慮了filename
包含 unicode 字符(即-, !, (, )
等)的情況,因此(utf-8 編碼)以例如filename*=utf-8''Na%C3%AFve%20file.txt
的形式出現filename*=utf-8''Na%C3%AFve%20file.txt
(有關詳細信息,請參見此處)。 在這種情況下, 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
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.