Javascript 使用 axios 强制下载 GET 请求
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43432892/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Force download GET request using axios
提问by Victor
I'm using vuejs 2 + axios. I need to send a get request, pass some params to server, and get a PDF as a response. Server uses Laravel.
我正在使用 vuejs 2 + axios。我需要发送一个 get 请求,将一些参数传递给服务器,并获得一个 PDF 作为响应。服务器使用 Laravel。
So
所以
axios.get(`order-results/${id}/export-pdf`, { params: { ... }})
makes successful request but it does not start force downloading, even though server returns correct headers.
发出成功的请求,但它不会开始强制下载,即使服务器返回正确的标头。
I think this is a typical situation when you need to, say, form a PDF report and pass some filters to server. So how could it be accomplished?
我认为这是一种典型的情况,例如,您需要形成 PDF 报告并将一些过滤器传递给服务器。那怎么可能实现呢?
Update
更新
So actually I found a solution. However the same approach didn't work with axios, don't know why, that's why I used raw XHR object. So the solution is to create a blob object and user createUrlObjectfunction. Sample example:
所以实际上我找到了一个解决方案。但是同样的方法不适用于 axios,不知道为什么,这就是我使用原始 XHR 对象的原因。所以解决方案是创建一个blob对象和用户createUrlObject函数。示例:
let xhr = new XMLHttpRequest()
xhr.open('POST', Vue.config.baseUrl + `order-results/${id}/export-pdf`, true)
xhr.setRequestHeader("Authorization", 'Bearer ' + this.token())
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
xhr.responseType = 'arraybuffer'
xhr.onload = function(e) {
if (this.status === 200) {
let blob = new Blob([this.response], { type:"application/pdf" })
let link = document.createElement('a')
link.href = window.URL.createObjectURL(blob)
link.download = 'Results.pdf'
link.click()
}
}
Important: you should have array buffer as response type
重要提示:您应该将数组缓冲区作为响应类型
However, the same code written in axios returns PDF which is empty:
但是,用 axios 编写的相同代码返回 PDF 是空的:
axios.post(`order-results/${id}/export-pdf`, {
data,
responseType: 'arraybuffer'
}).then((response) => {
console.log(response)
let blob = new Blob([response.data], { type: 'application/pdf' } ),
url = window.URL.createObjectURL(blob)
window.open(url); // Mostly the same, I was just experimenting with different approaches, tried link.click, iframe and other solutions
})
回答by Roshimon
You're getting empty PDF 'cause no data is passed to the server. You can try passing data using data object like this
您得到的是空的 PDF,因为没有数据传递到服务器。您可以尝试使用这样的数据对象传递数据
axios
.post(`order-results/${id}/export-pdf`, {
data: {
firstName: 'Fred'
},
responseType: 'arraybuffer'
})
.then(response => {
console.log(response)
let blob = new Blob([response.data], { type: 'application/pdf' }),
url = window.URL.createObjectURL(blob)
window.open(url) // Mostly the same, I was just experimenting with different approaches, tried link.click, iframe and other solutions
})
By the way I gotta thank you so much for showing me the hint in order to download pdf from response. Thank ya :)
顺便说一句,我非常感谢您向我展示提示,以便从回复中下载 pdf。谢谢你:)
var dates = {
fromDate: 20/5/2017,
toDate: 25/5/2017
}
The way in which I have used is,
我使用的方式是,
axios({
method: 'post',
url: '/reports/interval-dates',
responseType: 'arraybuffer',
data: dates
}).then(function(response) {
let blob = new Blob([response.data], { type: 'application/pdf' })
let link = document.createElement('a')
link.href = window.URL.createObjectURL(blob)
link.download = 'Report.pdf'
link.click()
})
回答by gtamborero
Try this: It works perfectly for me with compatibility for Internet Explorer 11 (createObjectURL doesn't work on Explorer 11)
试试这个:它与 Internet Explorer 11 的兼容性非常适合我(createObjectURL 不适用于 Explorer 11)
axios({
url: 'http://vvv.dev',
method: 'GET',
responseType: 'blob', // important
}).then((response) => {
if (!window.navigator.msSaveOrOpenBlob){
// BLOB NAVIGATOR
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'download.pdf');
document.body.appendChild(link);
link.click();
}else{
// BLOB FOR EXPLORER 11
const url = window.navigator.msSaveOrOpenBlob(new Blob([response.data]),"download.pdf");
}
});
https://gist.github.com/javilobo8/097c30a233786be52070986d8cdb1743
https://gist.github.com/javilobo8/097c30a233786be52070986d8cdb1743
回答by Deepak
I don't think its possible to do this in axios or even AJAX. The file will be kept in memory, i.e. you cannot save file to disk. This is because JavaScript cannot interact with disk. That would be a serious security issue and it is blocked in all major browsers.
我认为在 axios 甚至 AJAX 中都不可能做到这一点。该文件将保存在内存中,即您不能将文件保存到磁盘。这是因为 JavaScript 无法与磁盘交互。这将是一个严重的安全问题,并且在所有主要浏览器中都被阻止。
You can construct your URL in front-end and download it in the following way:
您可以在前端构建您的 URL 并通过以下方式下载它:
var url = 'http://example.com/order-results/' + id + '/export-pdf?' + '..params..'
window.open(url, '_blank');
Hope this helps!
希望这可以帮助!
回答by Bruno Soares
I tried some of the above suggested approaches but in my case the browser was sending me the popup block warning. The code described below worked for me:
我尝试了上述一些建议的方法,但在我的情况下,浏览器向我发送了弹出窗口阻止警告。下面描述的代码对我有用:
axios.get(url, {responseType: 'arraybuffer'})
.then(function (response) {
var headers = response.headers();
var blob = new Blob([response.data],{type:headers['content-type']});
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = "Your_file_name";
link.click();
});

