2015-09-13 3 views
2

SessionStorage неправильно настроен с использованием приведенного ниже сценария. Я пытаюсь установить хранилище в обратном вызове page.evaluate, но мне не повезло, и моя «полная» проверка прошла бесконечно. Я столкнулся с той же проблемой с casper, попробовав аналогичную модель оценки и перезагрузки. Я не могу проверить, потому что все запросы ajax используют sessionStorage для получения авторизации JWT. Я знаю, что у меня должен быть доступ к окну для оценки, поэтому я не уверен, почему это не работает.Как установить sessionStorage в PhantomJS и CasperJS?

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

ответ

3

Если вы устанавливаете 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, а затем загрузите страницу еще раз, чтобы на странице были получены значения.

  • Вы можете попытаться зарегистрироваться, чтобы как можно скорее задать значения сессии как page.onLoadStarted, page.onNavigationRequested или page.onUrlChanged.

Смежные вопросы