downloading a file that comes as an attachment in a POST request response in PhantomJs

vumaasha picture vumaasha · Apr 22, 2013 · Viewed 17.3k times · Source

I want to download a CSV file, it is generated on a button click through a POST request. I researched to my best on casperJs and phantomJS forums and returned empty handed. In a normal browser like firefox, a browser download dialog window appears after the post request. How to handle this case in PhantomJS

TTP/1.1 200 OK
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Vary: Accept-Encoding
Server: Microsoft-IIS/7.5
Content-disposition: attachment;filename=ExportData.csv
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET
Date: Fri, 19 Apr 2013 23:26:40 GMT
Content-Length: 65183

Answer

julianjm picture julianjm · May 7, 2014

I've found a way to do this using casperjs (it should work with phantomjs alone if you implement the download function using XMLHttpRequest, but i've not tried).

I'll leave you the working example, that tries to download the mos recent PDF from this page. When you click the download link, some javascript code is triggered that generates some hidden input fields that are then POSTed.

What we do is replace the form's onsubmit function so that it cancels the submission, and get the form destination (action) and all its fields. We use this information later to do the actual download.

var casper=require('casper').create();
casper.start("https://sede.gobcan.es/tributos/jsf/publico/notificaciones/comparecencia/ultimosanuncios.jsp", function() {

    var theFormRequest = this.page.evaluate(function() {
        var request = {}; 
        var formDom = document.forms["resultadoUltimasNotif"];
        formDom.onsubmit = function() {
            //iterate the form fields
            var data = {};
            for(var i = 0; i < formDom.elements.length; i++) {
               data[formDom.elements[i].name] = formDom.elements[i].value;
            }
            request.action = formDom.action;
            request.data = data;
            return false; //Stop form submission
        }

        //Trigger the click on the link.
        var link = $("table.listado tbody tr:first a");
        link.click();

        return request; //Return the form data to casper
    });

    //Start the download
    casper.download(theFormRequest.action, "downloaded_file.pdf", "POST", theFormRequest.data);
});

casper.run(); 

Note: you have to run it with --ignore-ssl-errors, as the CA they use isn't in your browser default CA list.

casperjs --ignore-ssl-errors=true downloadscript.js