Search code examples
jsfjsf-2html2canvas

Unexplained Aborted XHR


I have a menu item that, when clicked, captures a screenshot of the website and sends it to a backing bean. It uses the html2canvas library. The problem is that I'm getting random aborted XHRs and I can't figure out why.

Here is the code for the menu item:

<p:submenu label="Print" id="print">
        <p:menuitem value="Print Map in PDF" onclick="printMapPDF();"/>     
</p:submenu>

Here is the code for the function:

function printMapPDF() {

    console.log("test 1");

    html2canvas($('#mainForm\\:map'), {
        allowTaint : true,
        useCORS : true,
        onrendered : function(canvas) {
            console.log("test 2");
            var dataURL = canvas.toDataURL("image/png");
            var hidden = document.getElementById('mainForm:dataURLfield');
            hidden.setAttribute('value', dataURL);
            hidden.onchange();  
        }
    });

    console.log("test 3");

    return true;
}

'test 1' and 'test 3' appear on the console. Then, when the image is rendered, it calls the callback function, the XHR is aborted, and finally 'test 2' appears. I suppose the error must be happening when html2canvas is called, but I don't know what to do about this.

Any clues?


Solution

  • It's aborted because <p:menuitem> navigates to its (default) target URL. Simply let the onclick return false; to prevent the element from performing its default click behavior (usually, refreshing the current page).

    <p:menuitem ... onclick="printMapPDF(); return false;" />
    

    When the navigation happens before the ajax request gets sent, then you'll obviously get exactly this problem of an aborted XHR.


    That said, it's worth the effort to take a step back from JSF and learn some basic HTML and JavaScript first. Your concrete problem is not JSF related. JSF is in the context of this question merely a HTML code generator. You'd have had exactly the same problem when having a copy of JSF-generated HTML output in a plain .html file and the question would easily be answerable by users.