使用javascript下载时,PDF为空白

时间:2015-12-23 12:51:16

标签: 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=window.URL.createObjectURL(blob);
link.download="myBill.pdf";
link.click();
});

'response'包含来自'MyPdfFileAPIstreamURl'的servlet输出流的PDF字节数组。并且流也没有加密。

因此,当我点击该链接时,成功下载的PDF文件大小约为200KB。但是当我打开这个文件时,它会打开空白页面。下载的pdf文件的起始内容位于图像中。

我无法理解这里有什么问题。帮助!

这是下载的pdf文件起始内容:

This is the downloaded pdf file starting contents

3 个答案:

答案 0 :(得分:27)

solved it via XMLHttpRequest and xhr.responseType = 'arraybuffer'; code:

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();

答案 1 :(得分:20)

我从服务器获取数据作为字符串(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;
};

答案 2 :(得分:2)

我在React项目中面临着同样的问题。 在API上,我使用express的res.download()在响应中附加PDF文件。这样,我收到了一个基于字符串的文件。这就是文件打开空白或损坏的真正原因。

在我的情况下,解决方案是将responseType强制为'blob'。由于我是通过axios发出请求的,因此我只是在选项对象中添加了该属性:

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);