使用 Axios 从 http 响应下载 PDF
Posted
技术标签:
【中文标题】使用 Axios 从 http 响应下载 PDF【英文标题】:Download PDF from http response with Axios 【发布时间】:2019-01-02 00:10:02 【问题描述】:我正在开发一个带有 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));
,
【问题讨论】:
看看this link。虽然它在 asp.net 中,但您的服务器代码应该正确设置标题,以便客户端引起提示或显示 pdf。 【参考方案1】:正如@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));
,
【讨论】:
我还能够使用 downloadjs 使其适用于 PDF。谢谢你的提示。请注意,refereceType: 'blob'
是必需的。
很好的答案,直接工作..谢谢!
使用 arraybuffer 为我解决了这个问题。【参考方案2】:
您有两种选择。如果您想从服务器执行此操作,并且您使用 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)
)
由于服务器返回的响应是json
格式,你需要将其转换为ObjectURL
并设置为锚标记。
如果你潜入download.js
代码,你会发现相同的实现。
【讨论】:
正如您在我的帖子中看到的,我不使用 Node.js,但我使用 Laravel。无论如何,我会研究 download.jsdownload.js
与上述代码 sn-p 完全相同。
response.blob is not a function
。 // - 仅限浏览器:FormData、File、Blob。 // - 仅限节点:流、缓冲区。我正在开发一个 Node JS CLI 工具。我正在尝试使用stream
复制.blob()
方法。
我能够使用data.pipe(writer)
和writer.on("finish")
监听器来保存文件,然后在我的 CLI 工具中本地提供文件。【参考方案3】:
您应该使用“responseType”选项。例如:
axios.get(
url,
responseType: 'blob' // !!!
).then((response) =>
window.open(URL.createObjectURL(response.data));
)
【讨论】:
就是这样!为了正确接收来自服务器的 pdf,我必须在 httpService 调用的配置字段中使用responseType: 'arraybuffer'
。谢谢!【参考方案4】:
你可以这样做
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。
【讨论】:
以上是关于使用 Axios 从 http 响应下载 PDF的主要内容,如果未能解决你的问题,请参考以下文章
从请求响应创建 PDF 不适用于 axios,但适用于本机 xhr
无法通过 Vue.js(Axios 帖子)从 Laravel 后端下载文件(pdf)