Phantomjs在页面加载完成后登录、重定向和呈现页面

Phantomjs在页面加载完成后登录、重定向和呈现页面,phantomjs,Phantomjs,我有一个带有登录表单的网站。如果用户未登录并尝试访问内部页面,它将被重定向到默认页面。例如,如果我尝试访问 http://siteURL.PhantomPrint.aspx我将被重定向到http://siteURL/Default.aspx?ReturnUrl=PhantomPrint.aspx.登录后,将自动重定向到页面 在重定向之后,我想用Phantomjs呈现页面并将其保存为pdf。问题是渲染发生在页面加载完成之前,只有在使用超时时才能正确渲染页面。在这种情况下,如果页面加载时间比正常时间

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

在重定向之后,我想用Phantomjs呈现页面并将其保存为pdf。问题是渲染发生在页面加载完成之前,只有在使用超时时才能正确渲染页面。在这种情况下,如果页面加载时间比正常时间长,则生成的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);

欢迎就如何确保仅在重定向页面完成加载后才进行渲染提出任何建议。

经过进一步研究,我找到了解决方案,请参阅下面的代码

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)

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

看起来您希望处理导航步骤。如果发出页面加载/重定向,则需要使用来拾取。这可能很难维持。您还必须放弃使用带有
setInterval
的step数组的想法

另一种可能是使用指定的方法等待目标页面中存在的某个选择器,但这将使使用
setInterval
变得不可能


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

var casper=require('casper').create();
casper.on(“remote.message”,函数(msg){
控制台日志(msg);
});
casper.start(“http://siteURL/PhantomPrint.aspx“,函数(){
//输入凭据
这个。评估(函数(){
控制台日志(“填充输入”);
var usernameInput=document.getElementById(“txtUsername”);
usernameInput.value=“用户”;
var passwordInput=document.getElementById(“txtPassword”);
passwordInput.value=“password”;
});
点击此按钮;
此.echo(“已提交登录按钮”);
});
casper.then(函数(){
this.capture('example.png');
});
casper.run();

这可以通过使用变得更小。

我没有看到任何递归。您好,这听起来是一个很好的解决方案,但我有一个问题。我不能让PhantomJs和CasperJs一起工作。我收到以下错误“致命:系统找不到指定的文件;是否安装了phantomjs?”。我有我的PhantomJs目录,其中有PhantomJs.exe。在它里面我有一个子文件夹CasperJs,它有两个子文件夹:batchbin和bin。我要运行的js在CasperJs\bin中。如何配置casperjs以运行?因为我不知道,而且我现在无法在线找到任何合适的解决方案。您需要将phantomjs的位置(文件夹路径)添加到path环境变量中。如果您通过npm安装了phantomjs和casperjs,这将自动发生。