30

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.

Eric H.
  • 6,894
  • 8
  • 43
  • 62
  • 1
    the data string begins like this: `%PDF-1.5 %���� 2504 0 obj <> endobj 2511 0 obj <>/Filter/FlateDecode/ID[]/Index[2504 10]/Info 2503 0 R/Length 47/Prev 3720769/Root 2505 0 R/Size 2514/Type/XRef/W[1 2 0]>>stream h�bbd`b`9�����]�x?abP|...` – Eric H. Mar 18 '13 at 00:12
  • 1
    Just FYI to anyone. Ended up completely working around this issue because it didn't seem possible. I ended up serving the files temporarily for 10s, pointing an iframe to its arbitrary url, and removing them after download (no authentication other than browser cookies). – Eric H. Mar 03 '14 at 00:35

3 Answers3

43

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'
})...
Greenbeard
  • 508
  • 5
  • 14
Ciantic
  • 6,064
  • 4
  • 54
  • 49
  • Thank you, it works. But what if I don't know the type 'application/pdf' in prior? Can I use the MIME type from the response? – Yiping Dec 25 '16 at 02:37
  • Yes, you can use mimetype from the response. Note however, that this solution will *not* allow you to name the file that people end up downloading. It'll always be some nasty hash or something. – mlissner Nov 10 '17 at 01:26
  • can anyone suggest how to show pdf without third party API.. using XMLhttpReuqest or filereader. when we are selecting pdf file from fileupload control in html – Negi Rox May 08 '18 at 13:43
1

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();
LordDraagon
  • 521
  • 12
  • 31
1
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.

sanj singh
  • 59
  • 1
  • 3