Phantomjs登录,重定向和渲染页面加载完成后

时间:2014-09-10 13:15:27

标签: phantomjs

我有一个包含登录表单的网站。如果用户未登录并尝试访问内部页面,则会将其重定向到默认页面。例如,如果我尝试访问 http://siteURL.PhantomPrint.aspx我将被重定向到http://siteURL/Default.aspx?ReturnUrl=PhantomPrint.aspx.登录后,页面会自动重定向。

重定向后我想用Phantomjs渲染页面并将其保存为pdf。问题是渲染发生在页面加载完成之前,我只有在使用超时时才能正确呈现页面。在这种情况下,如果页面加载时间超过正常值,则生成的pdf不正确。

您可以在下面找到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);

有关如何确保仅在重定向页面完成加载后才能完成渲染的任何建议都受到欢迎。

2 个答案:

答案 0 :(得分:6)

您似乎想要处理导航步骤。如果发出了页面加载/重定向,您需要使用page.onNavigationRequested来获取。这可能很难维持。您还必须放弃使用setInterval的步骤数组的想法。

另一种可能性是使用waitFor专门等待目标页面中存在的某个选择器,但是再次,这将使setInterval无法使用。


CasperJS实际上构建在PhantomJS之上,并使用步骤来浏览网站。当您使用任何then*函数时,它将自动获取页面加载并等待页面加载完成,直到执行回调。

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

使用casper.fillSelectors可以做得更小。

答案 1 :(得分:0)

经过更多研究后我找到了解决方案,请参阅下面的代码。

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)

但我想知道是否没有其他解决方案不会涉及递归函数调用。

相关问题