簡體   English   中英

從 http 下載 PDF 響應 Axios

[英]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 添加到文件名中。

2022 答案:使用 node.js、fs.promises 和 async/await

關鍵是使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM