Properly Create and Serve PDF Blob via HTML5 File and URL APIs

Ok, Let's say I have document data stored somewhere, let's arbitrarily take this pdf.

Issue #1. What I want to do is make an AJAX call to this URL (because I need to pass some authentication headers and it is cross domain). Then take the returned data, create a blob url for it, append an iFrame to the DOM, and direct the src to the blob url.

Currently my code looks like this:

$.ajax({
  url:'http://www.grida.no/climate/ipcc_tar/wg1/pdf/tar-01.pdf'
}).done(function(data){
   var file = new Blob([data], {type:'application/pdf'}),
       url = URL.createObjectURL(file),
       _iFrame = document.createElement('iframe');
      _iFrame.setAttribute('src', url);
      _iFrame.setAttribute('style', 'visibility:hidden;');
      $('#someDiv').append(_iFrame);
});

Unfortunately, I am getting a 'Failed to Render PDF' in the iFrame.

Issue #2. I'd like this to result in a file download prompt. Not sure how to guarantee this given that PDF's will naturally just display in the iFrame.

Answers:

Answer

jQuery.ajax does not currently support blobs, see this bug report #7248 which is closed as wontfix.

However it's easy to do XHR for blobs without jQuery:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://www.grida.no/climate/ipcc_tar/wg1/pdf/tar-01.pdf', true);
xhr.responseType = 'blob';

xhr.onload = function(e) {
  if (this.status == 200) {
    // Note: .response instead of .responseText
    var blob = new Blob([this.response], {type: 'application/pdf'}),
        url = URL.createObjectURL(blob),
        _iFrame = document.createElement('iframe');

    _iFrame.setAttribute('src', url);
    _iFrame.setAttribute('style', 'visibility:hidden;');
    $('#someDiv').append(_iFrame)        
  }
};

xhr.send();

Shamelessly copied from HTML5rocks.

If jQuery did support the Blob type, it could be as simple as:

$.ajax({
  url:'http://www.grida.no/climate/ipcc_tar/wg1/pdf/tar-01.pdf',
  dataType:'blob'
})...
Answer

I have used @Ciantic answer to adapt my answer. I have avoided using iframe obj and the user can download the file directly from the page.

var link = 'http://www.grida.no/climate/ipcc_tar/wg1/pdf/tar-01.pdf';
$("body").addClass("loading"); // adding the loading spinner class

var xhr = new XMLHttpRequest();
xhr.open('GET',link,true);
xhr.responseType = 'blob';

        xhr.onload = function(e){
                 if (this.status == 200) {
                    var a = document.createElement('a');
                    var url = window.URL.createObjectURL(new Blob([this.response], {type: 'application/pdf'}));
                    a.href = url;
                    a.download = 'report.pdf';
                    a.click();
                    window.URL.revokeObjectURL(url);
                    $('body').removeClass("loading"); //removing the loading spinner class
                  }else{
                      $('body').removeClass("loading") //removing the loading spinner class
                      console.log(this.status);
                      alert('Download failed...!  Please Try again!!!');
                  }
            };
            xhr.send();
Answer
var src_url = your url here;
var contentDisposition = 'AlwaysInline';
var src_new = src_url.replace(/(ContentDisposition=).*?(&)/, '$1' + contentDisposition + '$2');

By doing this you will be able to view pdf instead of downloading it,

Header ContentDisposition should be 'AlwaysInline' then only it displays your file instead of downloading it.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.