我有一个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=window.URL.createObjectURL(blob); link.download="myBill.pdf"; link.click(); });
'response'包含来自'MyPdfFileAPIstreamURl'的servlet输出流的PDF字节数组.并且流也未加密.
因此,当我点击链接时,PDF文件成功下载大小约为200KB.但是当我打开这个文件时,它会打开空白页面.下载的pdf文件的起始内容位于图像中.
我无法理解这里有什么问题.救命 !
这是下载的pdf文件的起始内容:
通过XMLHttpRequest和xhr.responseType = 'arraybuffer';
代码解决了它:
var xhr = new XMLHttpRequest(); xhr.open('GET', './api/exportdoc/report_'+id, true); xhr.responseType = 'arraybuffer'; xhr.onload = function(e) { if (this.status == 200) { var blob=new Blob([this.response], {type:"application/pdf"}); var link=document.createElement('a'); link.href=window.URL.createObjectURL(blob); link.download="Report_"+new Date()+".pdf"; link.click(); } }; xhr.send();
我从服务器获取数据作为字符串(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; };