2014-09-10 16 views
6

Ho un sito Web con un modulo di accesso. Se un utente non è loggato e tenta di accedere a una pagina interna, verrà reindirizzato alla pagina predefinita. Ad esempio, se provo ad accedere a http://siteURL.PhantomPrint.aspx, verrai reindirizzato a http://siteURL/Default.aspx?ReturnUrl=PhantomPrint.aspx. E dopo l'accesso, un reindirizzamento automatico avverrà sulla pagina.Accesso Phantomjs, reindirizzamento e rendering pagina dopo pagina Caricamento terminato

Dopo il reindirizzamento voglio rendere la pagina con Phantomjs e salvarla come pdf. Il problema è che il rendering avviene prima che il caricamento della pagina sia terminato e posso renderizzare correttamente la pagina solo se utilizzo i timeout. In questo caso, se il caricamento della pagina richiede più tempo del normale, il pdf ottenuto non è quello corretto.

Qui di seguito potete trovare il codice java script:

var page = require('webpage').create(); 
var index = 0, 

page.onConsoleMessage = function (msg) { 
    console.log(msg); 
}; 

var steps = [ 
    function() { 
     //Load Login Page 
     page.open("http://siteURL.PhantomPrint.aspx", function() { 
      //Enter Credentials 
      page.evaluate(function() { 
       console.log("filling inputs"); 

      var usernameInput = document.getElementById("txtUsername"); 
      usernameInput.value = "user"; 

      var passwordInput = document.getElementById("txtPassword"); 
      passwordInput.value = "password"; 

      var loginButton = document.getElementById("btnLogin"); 
      loginButton.click(); 

      console.log("login button was submitted"); 
     }); 
    }); 
    }, 

    function() { 
      // page.onLoadFinished = function() { 
       // Render the page to pdf 
       page.render('example.png'); 
       phantom.exit(); 
       console.log("rendering finished"); 
      //}); 
     } 
    ]; 


    interval = setInterval(function() { 
     if (!loadInProgress && typeof steps[testindex] == "function") { 
      console.log("step " + (testindex + 1)); 
      steps[testindex](); 
      testindex++; 
     } 
     if (typeof steps[testindex] != "function") { 
      console.log("test complete!"); 
      phantom.exit(); 
     } 
    }, 1000); 

Qualche suggerimento su come posso assicurare che il rendering viene fatto solo dopo che la pagina reindirizzata sta finendo di carico vengono accolti.

risposta

0

Dopo ulteriori ricerche ho trovato una soluzione, vedere sotto il codice.

var loadInProgress = false; 

page.onLoadStarted = function() { 
    loadInProgress = true; 
    console.log("load started"); 
}; 

page.onLoadFinished = function() { 
    loadInProgress = false; 
    console.log("load finished"); 
}; 

interval = setInterval(function() { 
    if (!loadInProgress && typeof steps[testindex] == "function") { 
     console.log("step " + (testindex + 1)); 
     steps[testindex](); 
     testindex++; 
    } 
    if (typeof steps[testindex] != "function") { 
     console.log("test complete!"); 
     phantom.exit(); 
    } 
}, 100) 

Ma mi piacerebbe sapere se non c'è altra soluzione che non implichi chiamate di funzione ricorsive.

+1

Non vedo alcuna ricorsione. –

5

Sembra che si desidera elaborare i passaggi di navigazione. Dovresti utilizzare page.onNavigationRequested per prelevare se è stato emesso un caricamento/reindirizzamento della pagina. Questo sarà probabilmente difficile da mantenere. Dovresti anche scartare l'idea di utilizzare un array di passi con setInterval.

Un'altra possibilità potrebbe essere quella di attendere specificamente un selettore presente nella pagina di destinazione utilizzando waitFor, ma in tal caso, ciò renderebbe impossibile l'utilizzo di setInterval.


CasperJS è effettivamente costruita sulla sommità PhantomJS e utilizza passaggi per navigare il sito. Quando si utilizza una qualsiasi delle funzioni then*, verrà automaticamente caricato un caricamento della pagina e si attenderà il caricamento del caricamento della pagina fino all'esecuzione della richiamata.

var casper = require('casper').create(); 

casper.on("remote.message", function (msg) { 
    console.log(msg); 
}); 

casper.start("http://siteURL/PhantomPrint.aspx", function() { 
    //Enter Credentials 
    this.evaluate(function() { 
     console.log("filling inputs"); 

     var usernameInput = document.getElementById("txtUsername"); 
     usernameInput.value = "user"; 

     var passwordInput = document.getElementById("txtPassword"); 
     passwordInput.value = "password"; 
    }); 
    this.click("#btnLogin"); 
    this.echo("login button was submitted"); 
}); 
casper.then(function() { 
    this.capture('example.png'); 
}); 
casper.run(); 

questo può essere reso ancora più piccolo utilizzando casper.fillSelectors.

+0

Ciao, sembra una buona soluzione, ma ho un problema. Non riesco a far funzionare PhantomJs con CasperJs. Ricevo il seguente errore _ "Fatale: il sistema non riesce a trovare il file specificato; hai installato phantomjs?" _. Ho la mia directory PhantomJs in cui ho il phantomjs.exe. Al suo interno ho una sottocartella CasperJs che ha al suo turno 2 sottocartelle: _batchbin_ e _bin_. Il js che voglio eseguire è all'interno di CasperJs \ bin. Come posso configurare casperjs per l'esecuzione? Perché non ne ho idea e non sono riuscito a trovare alcuna soluzione adeguata online ormai. – AndraH

+0

È necessario aggiungere la posizione (percorso cartella) di phantomjs alla variabile di ambiente PATH. Se avessi installato phantomjs e casperjs attraverso npm, questo sarebbe successo automaticamente. –

Problemi correlati