使用javascript下载时,PDF为空
我有一个web服务,它在响应中返回PDF文件内容。我想在用户单击链接时将其下载为pdf文件。我在UI中编写的javascript代码如下:使用javascript下载时,PDF为空,javascript,pdf,Javascript,Pdf,我有一个web服务,它在响应中返回PDF文件内容。我想在用户单击链接时将其下载为pdf文件。我在UI中编写的javascript代码如下: $http.get('http://MyPdfFileAPIstreamURl').then(function(response){ var blob=new File([response],'myBill.pdf',{type: "text/pdf"}); var link=document.createElement('a'); link.href=wi
$http.get('http://MyPdfFileAPIstreamURl').then(function(response){
var blob=new File([response],'myBill.pdf',{type: "text/pdf"});
var link=document.createElement('a');
link.href=window.URL.createObjectURL(blob);
link.download="myBill.pdf";
link.click();
});
“response”包含来自“MyPdfFileAPIstreamURl”的servlet outputstream的PDF字节数组。而且流也没有加密
因此,当我点击链接时,一个大小约为200KB的PDF文件被成功下载。但当我打开这个文件时,它会打开空白页。下载的pdf文件的起始内容在图像中
我不明白这里怎么了。救命啊
这是下载的pdf文件的起始内容:
通过XMLHttpRequest和
xhr.responseType='arraybuffer'解决了这个问题代码>
代码:
我从服务器获取数据作为字符串(base64编码为字符串),然后在客户端将其解码为base64,然后解码为数组缓冲区
示例代码
function solution1(base64Data) {
var arrBuffer = base64ToArrayBuffer(base64Data);
// It is necessary to create a new blob object with mime-type explicitly set
// otherwise only Chrome works like it should
var newBlob = new Blob([arrBuffer], { type: "application/pdf" });
// IE doesn't allow using a blob object directly as link href
// instead it is necessary to use msSaveOrOpenBlob
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(newBlob);
return;
}
// For other browsers:
// Create a link pointing to the ObjectURL containing the blob.
var data = window.URL.createObjectURL(newBlob);
var link = document.createElement('a');
document.body.appendChild(link); //required in FF, optional for Chrome
link.href = data;
link.download = "file.pdf";
link.click();
window.URL.revokeObjectURL(data);
link.remove();
}
function base64ToArrayBuffer(data) {
var binaryString = window.atob(data);
var binaryLen = binaryString.length;
var bytes = new Uint8Array(binaryLen);
for (var i = 0; i < binaryLen; i++) {
var ascii = binaryString.charCodeAt(i);
bytes[i] = ascii;
}
return bytes;
};
函数解决方案1(base64Data){
var arrBuffer=base64ToArrayBuffer(base64Data);
//有必要创建一个显式设置mime类型的新blob对象
//否则,只有Chrome才能正常工作
var newBlob=newBlob([arrBuffer],{type:“application/pdf”});
//IE不允许将blob对象直接用作链接href
//相反,有必要使用msSaveOrOpenBlob
if(window.navigator&&window.navigator.msSaveOrOpenBlob){
window.navigator.msSaveOrOpenBlob(newBlob);
返回;
}
//对于其他浏览器:
//创建指向包含blob的ObjectURL的链接。
var data=window.URL.createObjectURL(newBlob);
var link=document.createElement('a');
document.body.appendChild(link);//FF中需要,Chrome可选
link.href=数据;
link.download=“file.pdf”;
link.click();
window.URL.revokeObjectURL(数据);
link.remove();
}
函数base64ToArrayBuffer(数据){
var binaryString=window.atob(数据);
var binaryLen=binaryString.length;
var bytes=新的Uint8Array(二进制数);
对于(var i=0;i
我在React项目中也面临同样的问题。
在API上,我使用express的res.download()将PDF文件附加到响应中。通过这样做,我收到了一个基于字符串的文件。这就是文件打开时空白或损坏的真正原因
在我的例子中,解决方案是强制responseType为“blob”。因为我是通过axios发出请求的,所以我只是在option对象中添加了这个属性:
axios.get('your_api_url_here', { responseType: 'blob' })
之后,要进行下载,您可以在“fetchFile”方法中执行以下操作:
const response = await youtServiceHere.fetchFile(id)
const pdfBlob = new Blob([response.data], { type: "application/pdf" })
const blobUrl = window.URL.createObjectURL(pdfBlob)
const link = document.createElement('a')
link.href = blobUrl
link.setAttribute('download', customNameIfYouWantHere)
link.click();
link.remove();
URL.revokeObjectURL(blobUrl);
您使用的媒体类型为“text/pdf”;这是自找麻烦,pdf不是一种文本格式,它是二进制的,把它当作文本处理会破坏它。请改为使用application/pdf。@mkl将其更改为application/pdf,但问题仍然相同。在此处使用text/pdf仍然是错误的。此外,您的屏幕截图看起来确实像是一行中的某个地方。一些代码将文件视为文本,使用单字节编码(拉丁文1)读取它,然后使用UTF-8写入它。这可能会帮助您:。添加responseType:blob
在AngularJS中对我很有效。这个答案帮助我找到了伴侣!谢谢。在桌面和安卓浏览器中工作正常。在iPhone(safari和chrome)上进行了测试,但没有成功。谢谢!使用createObjectURL有助于解决我遇到的失败的网络错误,但我的PDF无法打开,但您的解决方案使其正常工作。从2018年开始,使用chrome/windows 10,这一切都如愿以偿。太棒了!谢谢:)谢谢@Alexey,我也遇到了同样的问题,使用angularjs我不得不将responseType='arraybuffer'放在Hanks@Alexey上,我试图在React和typescript中使用axios解决同样的问题。我通过一些修改实现了上述解决方案,并使用1.1MB文件作为下载,以及iframe中的PDF视图。这也适用于现代库和获取,例如,axiosresponseType:“blob”
是必需的,我只能使用axios的responseType:“arraybuffer”
使其工作。我最初尝试使用responseType:“blob”
,然后用Buffer.from(例如blob,'binary')
转换为arraybuffer,但由于某种原因导致pdf文件损坏/格式不正确,这让我很高兴,谢谢你,伙计。
const response = await youtServiceHere.fetchFile(id)
const pdfBlob = new Blob([response.data], { type: "application/pdf" })
const blobUrl = window.URL.createObjectURL(pdfBlob)
const link = document.createElement('a')
link.href = blobUrl
link.setAttribute('download', customNameIfYouWantHere)
link.click();
link.remove();
URL.revokeObjectURL(blobUrl);