2014-09-10 6 views
6

Mam stronę internetową z formularzem logowania. Jeśli użytkownik nie jest zalogowany i próbuje uzyskać dostęp do strony wewnętrznej, zostanie przekierowany na stronę domyślną. Na przykład, jeśli spróbuję uzyskać dostęp do http://siteURL.PhantomPrint.aspx, nastąpi przekierowanie do http://siteURL/Default.aspx?ReturnUrl=PhantomPrint.aspx.. Po zalogowaniu nastąpi automatyczne przekierowanie na stronę.Logowanie phantomjs, przekierowanie i renderowanie strony po zakończeniu strony Kończenie

Po przekierowaniu chcę renderować stronę za pomocą Phantomjs i zapisać ją jako pdf. Problem polega na tym, że renderowanie ma miejsce przed zakończeniem ładowania strony i mogę poprawnie renderować stronę tylko wtedy, gdy używam limitu czasu. W takim przypadku, jeśli ładowanie strony trwa dłużej niż zwykle, wynikowy plik PDF nie jest prawidłowy.

Poniżej można znaleźć kod skryptu Java:

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

Wszelkie sugestie na temat w jaki sposób można zapewnić, że renderowanie odbywa się dopiero po przekierowany strona kończy ładowanie są mile widziane.

Odpowiedz

0

Po dalszych badaniach znalazłem rozwiązanie, patrz poniżej kod.

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) 

Ale chciałbym wiedzieć, czy nie ma innego rozwiązania, które nie wymagałoby rekurencyjnego wywoływania funkcji.

+1

Nie widzę żadnej rekursji. –

5

Wygląda na to, że chcesz przetworzyć kroki nawigacji. Musisz użyć page.onNavigationRequested, aby sprawdzić, czy zostało załadowane ładowanie/przekierowanie strony. Będzie to prawdopodobnie trudne do utrzymania. Trzeba też odrzucić pomysł użycia tablicy kroków z setInterval.

Inną możliwością byłoby konkretne oczekiwanie na jakiś selektor, który jest obecny na stronie docelowej przy użyciu waitFor, ale z drugiej strony uniemożliwiłoby to użycie setInterval.


CasperJS jest faktycznie zbudowany na szczycie PhantomJS i wykorzystuje kroki, aby poruszać się po witrynie. Podczas korzystania z dowolnej z funkcji then* automatycznie pobierze ładowanie strony i zaczeka na zakończenie ładowania strony do momentu wykonania wywołania zwrotnego.

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

Można to zrobić jeszcze mniej, używając casper.fillSelectors.

+0

Witam, to brzmi jak dobre rozwiązanie, ale mam jeden problem. Nie mogę zmusić PhantomJs do pracy z CasperJs. Otrzymuję następujący błąd _ "Fatal: system nie może znaleźć określonego pliku, czy zainstalowałeś phantomjs?" _. Mam mój katalog PhantomJs, w którym mam plik phantomjs.exe. Wewnątrz mam podfolder CasperJs, który ma na swoim 2 podfolderze: _batchbin_ i _bin_. Js, który chcę uruchomić, znajduje się wewnątrz CasperJs \ bin. Jak skonfigurować uruchamianie Caspers? Ponieważ nie mam pojęcia i nie mogłem znaleźć odpowiedniego rozwiązania online. – AndraH

+0

Musisz dodać lokalizację (ścieżkę folderu) phantomjs do zmiennej środowiskowej PATH. Jeśli zainstalowałbyś phantomjs i casperjs przez npm, nastąpiłoby to automatycznie. –