如何在 PhantomJS 和 CasperJS 中设置 sessionStorage?
How to set sessionStorage in PhantomJS and CasperJS?
使用以下脚本未正确设置 sessionStorage。我试图在 page.evaluate
回调中设置存储,但我没有任何运气,我的 "complete" 检查无限循环。我遇到了与 casper 完全相同的问题,尝试了类似的评估和重新加载模式。我无法测试,因为所有 ajax 请求都使用 sessionStorage 来获取授权 JWT。我知道我应该在评估中访问 window,所以我不确定为什么这不起作用。
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();
});
如果您在页面上下文中设置 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:
Note: The arguments and the return value to the evaluate
function must be a simple primitive object. The rule of thumb: if it can be serialized via JSON, then it is fine.
Closures, functions, DOM nodes, etc. will not work!
CasperJS中也是如此。
关于“循环”的主题。我发现您的代码存在三个问题。
首先Date.now
是对一个函数的引用。如果你想要当前时间,那么你必须将它称为 Date.now()
.
你没有给 PhantomJS 太多时间来做任何工作。您基本上使用 setTimeout()
没有第二个参数,默认为 0,这意味着立即调用回调。尝试使用较小的超时时间,例如 50:setTimeout(function(){...}, 50)
.
您正在尝试在页面上下文之外访问 document.getElementsByClassName('quoteTr')
,但 document
只是一个虚拟对象,因此无论发生什么情况,它总是 return 一个空数组在页面上。你必须使用 page.evaluate()
。 CasperJS 为这种情况提供 casper.exists()
函数。
我不是很明白为什么你需要设置一些sessionStorage
值,但如果你需要为页面尽快设置它们,那么你可以尝试采用两种不同的策略:
正常打开页面,将值设置为 sessionStorage
,然后再次加载页面,以便页面的 JavaScript 获取值。
您可以尝试注册page.onLoadStarted
、page.onNavigationRequested
或page.onUrlChanged
活动,以便尽快设置会话值。
使用以下脚本未正确设置 sessionStorage。我试图在 page.evaluate
回调中设置存储,但我没有任何运气,我的 "complete" 检查无限循环。我遇到了与 casper 完全相同的问题,尝试了类似的评估和重新加载模式。我无法测试,因为所有 ajax 请求都使用 sessionStorage 来获取授权 JWT。我知道我应该在评估中访问 window,所以我不确定为什么这不起作用。
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();
});
如果您在页面上下文中设置 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:
Note: The arguments and the return value to the
evaluate
function must be a simple primitive object. The rule of thumb: if it can be serialized via JSON, then it is fine.Closures, functions, DOM nodes, etc. will not work!
CasperJS中也是如此。
关于“循环”的主题。我发现您的代码存在三个问题。
首先Date.now
是对一个函数的引用。如果你想要当前时间,那么你必须将它称为 Date.now()
.
你没有给 PhantomJS 太多时间来做任何工作。您基本上使用 setTimeout()
没有第二个参数,默认为 0,这意味着立即调用回调。尝试使用较小的超时时间,例如 50:setTimeout(function(){...}, 50)
.
您正在尝试在页面上下文之外访问 document.getElementsByClassName('quoteTr')
,但 document
只是一个虚拟对象,因此无论发生什么情况,它总是 return 一个空数组在页面上。你必须使用 page.evaluate()
。 CasperJS 为这种情况提供 casper.exists()
函数。
我不是很明白为什么你需要设置一些sessionStorage
值,但如果你需要为页面尽快设置它们,那么你可以尝试采用两种不同的策略:
正常打开页面,将值设置为
sessionStorage
,然后再次加载页面,以便页面的 JavaScript 获取值。您可以尝试注册
page.onLoadStarted
、page.onNavigationRequested
或page.onUrlChanged
活动,以便尽快设置会话值。