Search code examples
javascriptphpsapui5jasperserver

Displaying a pdf served from Jasper Reports Server


My problem

I am retrieveng a report generated with Jasper Reports Server, with the intention of displaying it to the user in a new tab. I can create the new tab just fine, but the pdf is completely blank.

My code

I have to files, one php file that makes a request to the jasperserver, and another one that queries this file and creates the new tab using javascript. Javascript:

sap.ui.getCore().attachInit(function () {
    var onPress = function(evt){
        jQuery.ajax({
            type: "GET",
            url: "JasperReportAPICall.php",
            xhrFields: {responseType: "text/pdf"},
            data: {
              functionname: "authenticate",
              argument: "http://localhost:8080/jasperserver/rest_v2/reports/reports/interactive/Directives_Report.pdf?id=1&method=rules"
            },
            success: function(response){
                var blob = new Blob([response], {type: "application/pdf"});
                var pdfUrl = window.URL.createObjectURL(blob);
                var newTab = window.open(pdfUrl);
                newTab.addEventListener('load', function(pdfUrl){
                    window.URL.revokeObjectURL(pdfUrl);
                }, false);
                console.log("Report succesfully received");

            }
        });
    };
     new sap.m.Button({
         text: "GNR",
         press: onPress
     }).placeAt("content");
 });

PHP:

function authenticate($url){
    global $username, $pwd;

    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_GET, 1);
    curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    curl_setopt($curl, CURLOPT_USERPWD, "$username:$pwd");
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

    $result = curl_exec($curl);
    if (result===false){
        $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        $error = curl_error($curl);
        echo "HTTPCODE: $httpcode";
        echo "ERROR: $error";
    }

    curl_close($curl);
    return $result;
}

if (isset($_GET['functionname']) && isset($_GET['argument'])){
    if ($_GET['functionname'] === "authenticate"){

        $result = authenticate($_GET['argument']);
        echo $result;
    }
}

What I tried

  • Setting the xhr responsetype as 'blob'. window.URL.createObjectURL rejected it
  • Setting the xhr responseType as 'arraybuffer' and create a new Blob using said arraybuffer. Upon opening the new tab, pdf viewer complains it can't open the file
  • Same step as the previous one, but with a File object instead. same result.

What does the data look like

This is what I receive from the server.

Since it's too big to be put here, I put it in a pastebin.


Solution

  • I found a fix. The problem was on the PHP side. As it was, I retrieved the data, but didn't set the appropriate headers, thus when using the xhr responseType 'blob', it didn't have a mime type, causing a crash when using it to create an url object. Before returning the pdf to the ajax call, I set the headers like this.

    function authenticate($url){
        ...
        curl_close($curl);
        header('Cache-Control: public'); 
        header('Content-type: application/pdf');
        header('Content-Disposition: attachment; filename="new.pdf"');
        header('Content-Length: '.strlen($result));
        return $result;
    }
    

    With this, the pdf blob is served without any error.