![](/img/trans.png)
[英]How to download axios response from database in react as a pdf file?
[英]Download PDF from http response with Axios
我正在開發一個后端為 Laravel API 的 Vue 應用程序。單擊鏈接后,我想調用服務器以下載某個文件(大部分時間為 PDF 文件)。 當我使用axios
發出get
請求時,我在響應正文中得到 PDF 作為回報。 我想直接下載那個文件。
為了讓您更好地了解響應的樣子:
(注意:我知道真實的文本響應比圖像更好,但由於實際 PDF 內容的長度,我看不到任何返回方式。)
有什么辦法可以用 JavaScript 之類的方式下載那個文件嗎? 它必須是特定的直接下載而無需再次單擊按鈕。
代碼
// This method gets called when clicking on a link
downloadFile(id) {
const specificationId = this.$route.params.specificationId;
axios
.get(`${this.$API_URL}/api/v1/suppliersmanagement/product-specifications/${specificationId}/fileupload/${id}/download`, {
headers: this.headers,
})
.then(response => {
console.log(response);
// Direct download the file here..
})
.catch(error => console.log(error));
},
正如@Sandip Nirmal 建議的那樣,我使用了downloadjs
,效果非常好! 不得不對我的代碼進行一些調整,但最終它成功了。
我的新代碼
// npm i downloadjs
import download from 'downloadjs'
// method
downloadFile(file) {
const specificationId = this.$route.params.specificationId;
axios
.get(`${this.$API_URL}/api/v1/suppliersmanagement/product-specifications/${specificationId}/fileupload/${file.id}/download`, {
headers: this.headers,
responseType: 'blob', // had to add this one here
})
.then(response => {
const content = response.headers['content-type'];
download(response.data, file.file_name, content)
})
.catch(error => console.log(error));
},
您應該使用“responseType”選項。 例如:
axios.get(
url,
{responseType: 'blob'} // !!!
).then((response) => {
window.open(URL.createObjectURL(response.data));
})
為此,您有 2 個選項。 如果您想從服務器執行此操作,並且您使用 Node.js 作為后端。 您可以使用 express 的res.download
方法輕松完成。 您可以按照這個答案使用 Express 從 NodeJS 服務器下載文件。
但是,如果您想從客戶端處理它,那么選擇很少,因為您不能使用 axios、XHR、fetch 直接下載文件。 您可以使用download.js
或通過以下方式編寫自己的代碼。
return axios({
url: '/download', // download url
method: 'get',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
mode: 'no-cors'
}
})
.then(response => response.blob())
.then(blob => {
var url = window.URL.createObjectURL(blob)
var a = document.createElement('a')
a.href = url
a.download = fileName
a.click()
a.remove()
setTimeout(() => window.URL.revokeObjectURL(url), 100)
})
由於從服務器返回的響應是json
格式,您需要將其轉換為ObjectURL
並將其設置為錨標記。
如果你潛入download.js
代碼,你會發現相同的實現。
你可以這樣做
download(filename) {
fetch(url , { headers })
.then(response => response.blob())
.then(blob => URL.createObjectURL(blob))
.then(uril => {
var link = document.createElement("a");
link.href = uril;
link.download = filename + ".csv";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
});
}
在這里我想下載一個 CSV 文件,所以我將 .csv 添加到文件名中。
關鍵是使用responseType: 'stream'
per the Axios docs 。
import axios from 'axios';
import { writeFile } from 'fs/promises';
const downloadFile = async () => {
const response = await axios.get('https://someurl', {
params: {
// ...
},
// See https://axios-http.com/docs/api_intro
responseType: 'stream',
});
const pdfContents = response.data;
await writeFile('file.pdf', pdfContents);
};
const downloadPDF = (id, fileName) => {
axios({
method: 'get',
url: `https://api.example.com/pdf/invoice/${id}`,
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('token'),
'Content-Type': 'application/json'
},
responseType: 'blob'
}).then(function (response) {
const a = document.createElement('a');
a.href = window.URL.createObjectURL(response.data);
a.download = `${fileName}.pdf`;
document.body.appendChild(a);
a.click();
a.remove();
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.