27

I am returning stream data from laravel dompdf from this code

 $pdf = \App::make('dompdf.wrapper');
 $pdf->loadHTML("<div>This is test</div>");
 return $pdf->stream();

And this is my JS ajax code

    $.ajax({
        type:"GET",
        url: "/display",
        responseType: 'arraybuffer'
    }).done(function( response ) {
        var blob = new Blob([response.data], {type: 'application/pdf'});
        var pdfurl = window.URL.createObjectURL(blob)+"#view=FitW";
        $("#pdfviewer").attr("data",pdfurl);
    });

Here is HTML to display pdf after ajax

<object id="pdfviewer" data="/files/sample.pdf" type="application/pdf" style="width:100%;height:500px;"></object>

I am getting below error

Failed to load PDF document

Please help to fix this. How to display pdf file.

Chris Martin
  • 30,334
  • 10
  • 78
  • 137
GRESPL Nagpur
  • 2,048
  • 3
  • 20
  • 40

3 Answers3

18

jQuery.ajax() does not have a responseType setting by default. You can use a polyfill, for example jquery-ajax-blob-arraybuffer.js which implements binary data transport, or utilize fetch().

Note also, chrome, chromium have issues displaying .pdf at either <object> and <embed> elements, see Displaying PDF using object embed tag with blob URL, Embed a Blob using PDFObject. Substitute using <iframe> element for <object> element.

$(function() {

  var pdfsrc = "/display";

  var jQueryAjaxBlobArrayBuffer = "https://gist.githubusercontent.com/SaneMethod/" 
                         + "7548768/raw/ae22b1fa2e6f56ae6c87ad0d7fbae8fd511e781f/" 
                         + "jquery-ajax-blob-arraybuffer.js";

  var script = $("<script>");

  $.get(jQueryAjaxBlobArrayBuffer)
  .then(function(data) {
    script.text(data).appendTo("body")
  }, function(err) {
    console.log(err);
  })
  .then(function() {
    $.ajax({
      url: pdfsrc,
      dataType: "arraybuffer"
    })
    .then(function(data) {
      // do stuff with `data`
      console.log(data, data instanceof ArrayBuffer);
      $("#pdfviewer").attr("src", URL.createObjectURL(new Blob([data], {
            type: "application/pdf"
          })))
     }, function(err) {
          console.log(err);
     });

  });
});

Using fetch(), .arrayBuffer()

  var pdfsrc = "/display";

  fetch(pdfsrc)
  .then(function(response) {
    return response.arrayBuffer()
  })
  .then(function(data) {
    // do stuff with `data`
    console.log(data, data instanceof ArrayBuffer);
    $("#pdfviewer").attr("src", URL.createObjectURL(new Blob([data], {
        type: "application/pdf"
    })))
  }, function(err) {
      console.log(err);
  });

plnkr http://plnkr.co/edit/9R5WcsMSWQaTbgNdY3RJ?p=preview

version 1 jquery-ajax-blob-arraybuffer.js, jQuery.ajax(); version 2 fetch(), .arrayBuffer()

Community
  • 1
  • 1
guest271314
  • 1
  • 15
  • 104
  • 177
5

I like guest271314 answer a lot, especially the second version using fetch, but I wanted to add a solution that does not use a polyfill or an experimental technology like fetch.

This solution uses the native XMLHttpRequest API to create the request. This allows us to change the responseType to arrayBuffer.

  var xhr = new XMLHttpRequest();
  var pdfsrc = "https://upload.wikimedia.org/wikipedia/en/6/62/Definition_of_management.pdf";
  xhr.open('GET', pdfsrc, true);
  xhr.responseType = "arraybuffer";

  xhr.addEventListener("load", function (evt) {
    var data = evt.target.response;
    if (this.status === 200) {
      $("#pdfviewer").attr("src", URL.createObjectURL(new Blob([data], {
        type: "application/pdf"
      })));
    }
  }, false);

  xhr.send();

I forked guest271314s plnkr to show this method in action: http://plnkr.co/edit/7tfBYQQdnih9cW98HSXX?p=preview

Community
  • 1
  • 1
jobB
  • 411
  • 3
  • 10
3

From my tests the responce is in response not response.data, so the following should work:

  $.ajax({
        type:"GET",
        url: "/display",
        responseType: 'arraybuffer'
    }).done(function( response ) {
        var blob = new Blob([response], {type: 'application/pdf'});
        var pdfurl = window.URL.createObjectURL(blob)+"#view=FitW";
        $("#pdfviewer").attr("data",pdfurl);
    });

Although it seems JQuery is doing something with the responce causing a blank PDF output... (PDF is blank when downloading using javascript). This will work:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'test.pdf', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
   if (this.status == 200) {
        var blob=new Blob([this.response], {type:"application/pdf"});
        var pdfurl = window.URL.createObjectURL(blob)+"#view=FitW";
        $("#pdfviewer").attr("data",pdfurl);
   }
};
xhr.send();
Community
  • 1
  • 1
Andrew Monks
  • 656
  • 4
  • 11
  • after changing `response.data` to `response` I am getting completely blank pdf. no output. I think we are near to fix this, may be need to change in `responseType` or `Content-type` any where. – GRESPL Nagpur Feb 11 '17 at 09:26
  • @AndrewMonks _"From my tests the responce is in response not response.data, so the following should work"_ Can you share tests at a stacksnippets, jsfiddle http://jsfiddle.net, or plnkr http://plnkr.co ? – guest271314 Feb 13 '17 at 05:05
  • unfortunately not as you cannot upload a pdf file to a snippet site and CORs blocks requests to other sites PDF files. Allthough see http://stackoverflow.com/questions/34436133/pdf-is-blank-when-downloading-using-javascript I checked again and was getting a blank output. Try using a raw XMLHttpRequest instead of jquery and it will work. – Andrew Monks Feb 13 '17 at 10:13
  • @AndrewMonks `jQuery.ajax()` does not have a `responseType` setting by default. – guest271314 Feb 13 '17 at 18:59