从请求响应创建 PDF 不适用于 axios,但适用于本机 xhr
Posted
技术标签:
【中文标题】从请求响应创建 PDF 不适用于 axios,但适用于本机 xhr【英文标题】:Creating PDF from request response doesn't work with axios but works in native xhr 【发布时间】:2017-09-27 02:07:33 【问题描述】:为了强制从服务器下载 PDF,我尝试使用 axios 和本机 xhr 对象。原因是我必须发送 post 请求,因为我向服务器传递了太多数据,所以带有简单链接的选项(如 site.ru/download-pdf
对我不起作用)。
即使我最终设法用 Xhr 做到了这一点,我仍然不知道为什么 axios 方式不起作用。
这是我使用 xhr 执行此操作的方法,它适用于我:
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()
;
xhr.send("data=" + data);
这是“axios-way”,我实际上得到了页数正确的 PDF,但它们都是空的:
axios.post(`order-results/$id/export-pdf`,
data,
responseType: 'arraybuffer'
).then((response) =>
let blob = new Blob([response.data], type:"application/pdf" )
let link = document.createElement('a')
link.href = window.URL.createObjectURL(blob)
link.download = 'Results.pdf'
link.click()
)
Axios 已配置为发送授权令牌。
我将Application/x-www-form-urlencoded
放在 xhr 中,否则我无法在服务器端获取数据。
即使 xhr 有效,我还是更喜欢使用 axios,因为我到处都在使用它,而且我只是好奇我做错了什么。我尝试了不同的解决方案,只有原生 xhr 完成了这项工作。
【问题讨论】:
Force download GET request using axios的可能重复 【参考方案1】:以下对我有用:
axios.post("http://localhost:8080/reports/my-report/",
data,
responseType: 'arraybuffer',
headers:
'Content-Type': 'application/json',
'Accept': 'application/pdf'
)
.then((response) =>
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'file.pdf'); //or any other extension
document.body.appendChild(link);
link.click();
)
.catch((error) => console.log(error));
如果这有帮助,请告诉我。
干杯!
【讨论】:
它有效。我在请求配置中想念responseType: 'arraybuffer'
。
这很好用,就目前而言。现在,如何使用来自服务器的文件名? content-disposition: attachment; filename="My Test - Doc Title.pdf"
responseType: 'arraybuffer'
做了什么让它如此重要?
这真的很有帮助。谢谢【参考方案2】:
无论出于何种原因,pdf 正在下载,但传递的任何内容都没有出现,从而导致空白 pdf。
我发现此代码 sn-p 相似,但会生成包含内容的 pdf。
axios(
url: '/pdf',
method: 'GET',
responseType: 'blob', // important
).then((response) =>
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'file.pdf');
document.body.appendChild(link);
link.click();
);
有一些反馈说它在 IE 11 上不起作用,我没有对其进行测试,但使用 FileSaver.js 发布了解决方案
axios(
url: '/pdf',
method: 'GET',
responseType: 'blob', // important
).then((response) =>
FileSaver.saveAs(new Blob([response.data]));
);
【讨论】:
这是一个 get 请求,它返回显示正常的 pdf,但 post 请求似乎会影响响应数据,从而导致空白 pdf【参考方案3】:有一个特殊的responseType:'blob':
axios.post(`order-results/$id/export-pdf`,
data,
responseType: 'blob'
).then((response) =>
let link = window.URL.createObjectURL(blob)
link.download = 'Results.pdf'
link.click()
)
或者你可以使用window.open
方法:
axios.post(`order-results/$id/export-pdf`,
data,
responseType: 'blob'
).then((response) =>
window.open(URL.createObjectURL(response.data));
)
【讨论】:
【参考方案4】:您得到的是空 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
);
顺便说一句,我非常感谢您向我展示了提示,以便从响应中下载 pdf。谢谢你:)
var dates =
fromDate: 20/5/2017,
toDate: 25/5/2017
我使用的方式是,
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();
);
【讨论】:
哦,对不起那个伙伴。以上是关于从请求响应创建 PDF 不适用于 axios,但适用于本机 xhr的主要内容,如果未能解决你的问题,请参考以下文章