使用Axios从http响应下载PDF

Gij*_*rts 4 javascript http vue.js axios

我正在使用Laravel后端API开发Vue应用程序。单击链接后,我想调用服务器以下载特定文件(大多数情况下为PDF文件)。当我getaxios我发送请求时,会在响应的正文中得到一个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));
},
Run Code Online (Sandbox Code Playgroud)

Sla*_*ava 28

您应该使用“responseType”选项。例如:

axios.get(
  url, 
  {responseType: 'blob'} // !!!
).then((response) => {
  window.open(URL.createObjectURL(response.data));
})
Run Code Online (Sandbox Code Playgroud)

  • 就是这样!为了正确地从服务器接收 pdf,我必须在 httpService 调用的配置字段中使用 `responseType: 'arraybuffer'`。谢谢你! (2认同)

San*_*mal 8

为此,您有两种选择。如果您想从服务器执行此操作并且使用 Node.js 作为后端。res.download您可以使用快递方法轻松完成。您可以按照此答案下载Download a file from NodeJS Server using Express

但如果你想从客户端处理它,那么几乎没有选择,因为你不能使用 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)
    })
Run Code Online (Sandbox Code Playgroud)

由于从服务器返回的响应是json格式的,因此您需要将其转换为ObjectURL锚标记并将其设置为锚标记。

如果你潜入download.js代码,你会发现相同的实现。


Gij*_*rts 7

正如@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));
},
Run Code Online (Sandbox Code Playgroud)

  • 我还可以使用 downloadjs 使其适用于 PDF。谢谢你的提示。人们应该注意,“refereceType: 'blob'”是必需的。 (2认同)
  • 这是一种解决方法,但没有回答“如何使用 Axios 从 http 响应下载 PDF”的问题。 (2认同)

mik*_*ana 6

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

关键是使用responseType: 'stream'Axios 文档

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

Run Code Online (Sandbox Code Playgroud)