2014-09-10 23 views
6

Ich habe eine Website mit einem Login-Formular. Wenn ein Benutzer nicht angemeldet ist und versucht, auf eine interne Seite zuzugreifen, wird er auf die Standardseite umgeleitet. Zum Beispiel, wenn ich versuche, auf http://siteURL.PhantomPrint.aspx zuzugreifen, werde ich auf http://siteURL/Default.aspx?ReturnUrl=PhantomPrint.aspx. umgeleitet werden und nach dem Login wird eine automatische Weiterleitung auf der Seite stattfinden.Phantomjs Login, Redirect und Render Seite nach SeiteLoad beendet

Nach der Umleitung möchte ich die Seite mit Phantomjs rendern und als PDF speichern. Das Problem besteht darin, dass das Rendering vor dem Laden der Seite erfolgt und ich die Seite nur dann richtig rendern kann, wenn ich Timeouts verwende. In diesem Fall, wenn das Laden der Seite länger als normal dauert, ist die resultierende PDF nicht die richtige.

Unten können Sie die Java-Script-Code finden:

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); 

Vorschläge, wie ich das Rendering erfolgt nur versichern kann, nachdem die umgeleitet Seite geladen wird Schlichten begrüßt.

Antwort

0

Nach mehr Forschung fand ich eine Lösung, siehe unten Code.

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) 

Aber ich würde gerne wissen, ob es keine andere Lösung gibt, die nicht rekursiv Funktion aufrufen würde.

+1

Ich sehe keine Rekursion. –

5

Es sieht so aus, als ob Sie Navigationsschritte verarbeiten möchten. Sie müssten page.onNavigationRequested verwenden, um abzuholen, wenn eine Seite geladen/umgeleitet wurde. Dies wird wahrscheinlich schwer aufrechtzuerhalten sein. Sie müssten auch die Idee, ein Schritt-Array mit setInterval zu verwenden, verwerfen.

Eine andere Möglichkeit wäre, gezielt auf einen Selektor zu warten, der auf der Zielseite mit waitFor vorhanden ist, aber dann wiederum würde dies die Verwendung von setInterval unmöglich machen.


CasperJS ist eigentlich oben auf PhantomJS gebaut und verwendet vor, um die Seite zu navigieren. Wenn Sie eine der then*-Funktionen verwenden, wird automatisch eine Seitenladung gestartet und auf das Laden der Seite gewartet, bis der Rückruf ausgeführt wird.

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(); 

Dies kann durch Verwendung casper.fillSelectors noch kleiner gemacht werden.

+0

Hallo, es klingt wie eine gute Lösung, aber ich habe ein Problem. Ich kann PhantomJs nicht mit CasperJs arbeiten lassen. Ich erhalte den folgenden Fehler _ "Fatal: Das System kann die angegebene Datei nicht finden; haben Sie phantomjs installiert?" _. Ich habe mein PhantomJs Verzeichnis, wo ich die phantomjs.exe habe. Darin habe ich einen Unterordner CasperJs, der an seinem Zug 2 Unterordner hat: _batchbin_ und _bin_. Die js, die ich ausführen möchte, ist in CasperJs \ bin. Wie kann ich Casperjs für die Ausführung konfigurieren? Weil ich keine Ahnung habe und ich online keine passende Lösung finden konnte. – AndraH

+0

Sie müssen den Standort (Ordnerpfad) von phantomjs der PATH-Umgebungsvariablen hinzufügen. Wenn Sie phantomjs und casperjs über npm installiert hätten, wäre dies automatisch geschehen. –