【问题标题】:How to set sessionStorage in PhantomJS and CasperJS?如何在 PhantomJS 和 CasperJS 中设置 sessionStorage?
【发布时间】:2015-09-14 04:51:54
【问题描述】:

没有使用以下脚本正确设置 sessionStorage。我正在尝试在page.evaluate 回调中设置存储,但我没有运气,我的“完整”检查无休止地循环。我在 casper 上遇到了同样的问题,尝试了类似的评估和重新加载模式。我无法测试,因为所有 ajax 请求都使用 sessionStorage 来获取授权 JWT。我知道我应该可以在评估中访问窗口,所以我不确定为什么这不起作用。

var page = require("webpage").create();
var url = "http://xxxxxxxx.com";
var t0 = Date.now;
function onPageReady() {
    var t1 = Date.now;
    var elapsed = t1 - t0; 
    var htmlContent = page.evaluate(function () {
        return document.documentElement.outerHTML;
    }); 
    console.log(htmlContent);
    console.log("ELAPSED TIME: " , elapsed + "\n") ;
    phantom.exit(0);
}

page.open(url, function (status) {
    var sessionStorage = page.evaluate(function(){
      sessionStorage.setItem('authorization','xxxxxxxxxxxxxxxxx');
      //window.sessionStorage.setItem('authorization','xxxxxxxxxx');
      window.sessionStorage.setItem('_USER','value');
      window.sessionStorage.setItem('USERNAME','value');
      window.sessionStorage.setItem('INTERNAL','value');
      console.log(window.sessionStorage);
      return sessionStorage;
    }); 
    t0 = Date.now;
    console.log(JSON.stringify(sessionStorage));
    console.log(JSON.stringify(window.sessionStorage));
    function checkReadyState() {
        setTimeout(function () {
            var readyState = page.evaluate(function () {
                return document.readyState;
            }); 

            if ("complete" === readyState) {
              // checking if my ng-repeat has loaded
              if (document.getElementsByClassName('quoteTr').length > 1){ 
                  console.log("ready!")
                  onPageReady();
              } else {
                  console.log("script not complete")
                  checkReadyState();
              }   
            } else {
                checkReadyState();
            }   
        }); 
    }   

    checkReadyState();
});

【问题讨论】:

    标签: javascript phantomjs casperjs session-storage


    【解决方案1】:

    如果您在页面上下文中设置sessionStorage(在page.evaluate() 中),那么您需要在页面上下文中检索它。虽然sessionStorage 存在于页面上下文之外,但它是一些虚拟对象,无法访问页面的sessionStorage

    page.evaluate(function(){
        sessionStorage.setItem('authorization','xxxxxxxxxxxxxxxxx');
    });
    var authorization = page.evaluate(function(){
        sessionStorage.getItem('authorization');
    });
    console.log("authorization: " + authorization);
    

    由于sessionStorage 是一个非原始对象,您不能将它传递到页面上下文之外。您只能传递它的表示形式,例如它的键值对。对于docs

    注意:evaluate 函数的参数和返回值必须是简单的原始对象。经验法则:如果可以通过 JSON 序列化就可以了。

    闭包、函数、DOM 节点等将起作用!

    在 CasperJS 中也是如此。


    关于“循环”的主题。我发现您的代码存在三个问题。

    第一个Date.now 是对函数的引用。如果您想要当前时间,则必须将其称为Date.now()

    你没有给 PhantomJS 太多时间来做任何工作。您实际上是在使用 setTimeout() 而不使用默认为 0 的第二个参数,这意味着立即调用回调。尝试使用较小的超时时间,例如 50:setTimeout(function(){...}, 50)

    您试图在页面上下文之外访问document.getElementsByClassName('quoteTr'),但document 只是一个虚拟对象,因此无论页面上发生什么,它都将始终返回一个空数组。您必须使用page.evaluate()。 CasperJS 为这种情况提供了casper.exists() 函数。


    我还没有完全理解为什么你需要设置一些sessionStorage 值,但是如果你需要尽快为页面设置它们,那么你可以尝试采用两种不同的策略:

    • 正常打开页面,将值设置为sessionStorage,然后再次加载页面,以便页面的 JavaScript 获取值。

    • 您可以尝试注册page.onLoadStartedpage.onNavigationRequestedpage.onUrlChanged 活动,以便尽快设置会话值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      • 2012-12-15
      • 1970-01-01
      相关资源
      最近更新 更多