PDF is blank when downloading using javascript

前端 未结 3 1463
天涯浪人
天涯浪人 2020-12-02 13:20

I have a web service that returns PDF file content in its response. I want to download this as a pdf file when user clicks the link. The javascript code that I have written

相关标签:
3条回答
  • 2020-12-02 13:57

    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();
    
    0 讨论(0)
  • 2020-12-02 14:02

    i fetched the data from server as string(which is base64 encoded to string) and then on client side i decoded it to base64 and then to array buffer.

    Sample code

    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;
    };
    
    0 讨论(0)
  • 2020-12-02 14:20

    I was facing the same problem in my React project. On the API I was using res.download() of express to attach the PDF file in the response. By doing that, I was receiving a string based file. That was the real reason why the file was opening blank or corrupted.

    In my case the solution was to force the responseType to 'blob'. Since I was making the request via axios, I just simply added this attr in the option object:

    axios.get('your_api_url_here', { responseType: 'blob' })
    

    After, to make the download happen, you can do something like this in your 'fetchFile' method:

    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);
    
    0 讨论(0)
提交回复
热议问题