Display PDF using an AJAX call

67,808

Solution 1

Why do you load it via AJAX? Why don't you load it in an IFRAME that you generate when you need it. The standard browsers plugin will display it then inside that Iframe.

$('#link').click(function(e) {
    e.preventDefault(); // if you have a URL in the link
    jQuery.ajax({
        type: "POST",
        processData: false,
        url: "aaaa.p?name=pdf",
        data: inputxml,
        contentType: "application/xml; charset=utf-8",
        success: function(data)
        {
            var iframe = $('<iframe>');
            iframe.attr('src','/pdf/yourpdf.pdf?options=first&second=here');
            $('#targetDiv').append(iframe);
        }
    });
});

Solution 2

Here is my way of dealing with this issue. It is based on line 50 of this pdfmake file (https://github.com/bpampuch/pdfmake/blob/master/src/browser-extensions/pdfMake.js).

  1. assuming you have a pdf stream I convert it to base64 and echo it back to my AJAX:

    $pdfString = $mpdf->Output('', 'S');
    $pdfBase64 = base64_encode($pdfString);
    echo 'data:application/pdf;base64,' . $pdfBase64;
    
  2. Here is my AJAX code. When receiving data it opens a new window and replaces url with base64 endoded data:

    var ajaxRequest = $.ajax({
        url: "php/generate-pdf/print-control.php",
        data: '',
        cache: false,
        contentType: 'application/json',
        processData: false,
        type: 'POST'
    
    });
    $.when(ajaxRequest).done(function (ajaxValue) {
        var win = window.open('', '_blank');
        win.location.href = ajaxValue;
    });
    

    The downside of this method is that you get a base64 string in the adress bar.

Solution 3

For anybody that stumbles across this. Here is an example using axios

  1. responseType must be 'arrayBuffer'
  2. create a Blob object from response
  3. create an "object url" from the blob that you can load into the iframe

        axios({
            url: `path/to/pdf`,
            method: "GET",
            responseType: 'arraybuffer'
        }).then((response) => {
            let blob = new Blob([response.data], { type: response.headers['content-type'] } );
            let url = window.URL.createObjectURL(blob);
    
            $('#frame').attr('src',url);
        });
    
Share:
67,808
Knissanka
Author by

Knissanka

I m working as a Software Architect

Updated on July 20, 2022

Comments

  • Knissanka
    Knissanka almost 2 years

    I'm trying to display a PDF(which is created in the server side and pass to the client side as a web stream) through an AJAX call. My code is given below:

    jQuery.ajax({
        type: "POST",
        processData: false,
        url: "aaaa.p?name=pdf",
        data: inputxml,
        contentType: "application/xml; charset=utf-8",
        success: function(data)
        {
          // here the data is the PDF stream i'm getting from the server side. 
    
        }
    });
    

    The 'inputxml' is containing input parameters for the server to create the PDF. and the 'data' in the success function containing PDF stream. Is there any way to open the PDF file on the browser inside the success function of the AJAX call with-out doing any page submit? In the server side the PDF is not physically generated also. Highly appreciate your help....

  • Knissanka
    Knissanka over 11 years
    Thanks for the quick respond. Can you give me some working example?
  • Knissanka
    Knissanka over 11 years
    Thanks for the quick respond. In my situation the PDF file is not physically generated on the server. And I need the AJAX call to send the input parameters to the server side.
  • Zim84
    Zim84 over 11 years
    I added something. inputxml must be converted to parameters for the URL request, but that shouldn't be a problem.
  • lethal-guitar
    lethal-guitar over 11 years
    Well, I see no way how to "download" a PDF file using AJAX. Either the data is processed by the browser, which can result in a download - or by JavaScript, which usually triggers DOM insertion etc. You would need a way to convert the PDF to HTML in order to display it - theoretically possible, but JavaScript is not really meant to do that, and that's probably not what you want.
  • lethal-guitar
    lethal-guitar over 11 years
    Using GET parameters instead of POST is not an option?
  • Knissanka
    Knissanka over 11 years
    Thanks for the reply, but the issue is the inputxml is bit large and containing lot of data. I don't think its possible to put it to the URL as a query string.
  • Knissanka
    Knissanka over 11 years
    Is there any jquery plugin which help me to do this?
  • Zim84
    Zim84 over 11 years
    Then you can send the inputxml via AJAX and when the server tells you everything is ok you can insert the iframe. In the comment from a different post you said that the xmldata and the pdf aren't correlated, so this should work.
  • Knissanka
    Knissanka over 11 years
    yes. instead of iframe.attr('src','/pdf/yourpdf.pdf?options=first&second=her‌​e'); Can I add the returned value from the AJAX success function to the iFrame.? (instead of specifying the src, because the respond not containing any URL, but only the PDF stream)
  • Zim84
    Zim84 over 11 years
    What data do you get back? if the only data is the PDF itself, no.
  • Zim84
    Zim84 over 11 years
    As said by other answers, you can't use this data in jQuery. This will be binary data. You need a plugin that interprets this data. You can either open a new window, use the same window, open a new frame or use an iframe to call the plugin that handels the PDF or offer the pdf as a download. Luckily a PDF plugin is common so you don't have to worry about that.
  • Zim84
    Zim84 over 11 years
    Well, nearly every PDF-viewer also has a plugin for browsers.. the most common is from adobe I guess.
  • Zim84
    Zim84 over 8 years
    @Yosep Kim Can you expain why not?
  • Yosep Kim
    Yosep Kim over 8 years
    @Zim84 Never mind. I misunderstood. Your solution is based on getting a real PDF file and opening it in an IFRAME, right? You can in fact set the byte stream of a PDF file to SRC of the IFRAME, however, this does NOT work on IE.
  • Mistre83
    Mistre83 over 7 years
    Thanks a lot!!! After day of search this is the only answer that not display a blank pdf :)
  • Miguelito
    Miguelito over 6 years
    @Zim88 - --You can in fact set the byte stream of a PDF file to SRC of the IFRAME--. Well, that is what I am trying without much luck, It is giving a 404 error., Any suggestions? I've seena way to save the blob to file (maybe), but I think I will get a -Local file open- error
  • The Terrible Child
    The Terrible Child almost 5 years
    This answer should be the accepted one. It solved my problem since i always use GET for rendering PDF with html2canvas image. Since GET can't accomodate the length of the base64 encoded image, i did a rough workaround to get it work until i saw this one. :)
  • somesayinice
    somesayinice almost 5 years
    Thanks so much. Works well when combined with download.js like this $.ajax({... success: function(data) {download(data, "test.pdf", "application/pdf");}); See the binary section of download.js
  • Daantje
    Daantje almost 3 years
    You saved my day! Thx!