Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 948
Eric H. Avatar asked Mar 17 '13 23:03

Eric H.


People also ask

How do I create a blob in HTML?

To construct a Blob from other non-blob objects and data, use the Blob() constructor. To create a blob that contains a subset of another blob's data, use the slice() method. To obtain a Blob object for a file on the user's file system, see the File documentation.

How do I create a blob URL?

You can use URL. createObjectURL() to create Blob url. The URL. createObjectURL() static method creates a DOMString containing a URL representing the object given in the parameter.

Can pdf be stored as BLOB?

MySQL has the BLOB datatype that can be used to store files such as . pdf, . jpg, .

How do I convert a PDF to a blob?

To convert a base64 string representing PDF to a blob with JavaScript, we can use fetch . to define the b64toUrl function that gets the base64Data URL string. In it, we call fetch with base64Data to load the URL into the r response object. Then we get a blob from it with r.


3 Answers

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' })... 
like image 77
Ciantic Avatar answered Sep 20 '22 20:09

Ciantic


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();
like image 29
LordDraagon Avatar answered Sep 22 '22 20:09

LordDraagon


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.

like image 27
sanj singh Avatar answered Sep 22 '22 20:09

sanj singh