我正试图通过模拟它在phantomjs上做的部分来测试一个chrome插件。
我想要幻影做什么似乎非常简单,但我遇到了问题。我希望它访问某个网页,并在此页面的上下文中运行一个脚本,该脚本将向我的后端发送ajax请求并打印出响应。为了让我的生活更轻松,我希望幻影使用jQuery来发送ajax请求。
所以这是我传给幽灵的脚本test1.js
:
var page = new WebPage(),
url = 'http://www.example.com',
// Callback is executed each time a page is loaded...
page.open(url, function (status) {
if (status === 'success') {
console.log('opened url');
start();
}
});
function start(){
page.includeJs('https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js', function() {
console.log("got here");
$.get("http://my-wonderful-site.com")
.done(function( data ) {
console.log("here!");
console.log(data);
phantom.exit();
});
});
}
命令phantomjs test1.js --web-security=false
的控制台输出是:
opened url
got here
ReferenceError: Can't find variable: $
test1.js:20
:/modules/webpage.js:337
所以看起来即使jQuery也没有加载,但我无法弄清楚我做错了什么。试过page.injectJs从我的硬盘驱动器注入jQuery,但得到了同样的错误。你能帮忙吗?
编辑:
按建议更新了该功能:
function start(){
page.includeJs('https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js', function() {
console.log("got here");
page.evaluate(function() {
console.log("and here");
$.get("http://my-wonderful-site.com")
.done(function( data ) {
console.log("here!");
console.log(data);
phantom.exit();
});
});
});
}
现在幻像挂起,控制台输出为:
phantomjs test1.js --web-security=false
opened url
got here
也就是说,$.get
之前的console.log甚至没有执行。
答案 0 :(得分:2)
PhantomJS有两个上下文。内部上下文或页面上下文由page.evaluate()
定义。它是沙盒的,无法访问外部定义的变量。所以,它不知道phantom
是什么。以同样的方式,外部上下文不知道$
是什么,因为jQuery是一个DOM库并被注入到页面中。您需要在page.evaluate()
中包装您的jQuery请求。
另一件事是,现在,phantom.exit()
并不意味着什么。您需要告诉PhantomJS从页面上下文中退出,因为请求是异步的。这就是page.onCallback
and window.callPhantom()
对进来的地方。
page.onCallback = function(data){
if (data.type === "exit") {
phantom.exit();
}
};
function start(){
page.includeJs('https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js', function() {
console.log("got here");
page.evaluate(function(){
$.get("http://my-wonderful-site.com")
.done(function( data ) {
console.log("here!");
console.log(data);
window.callPhantom({type: "exit"});
});
});
});
}
console.log()
是在页面上下文中定义的,但您无法在那里看到它,因为PhantomJS默认情况下不会将它们传递出去。您必须注册page.onConsoleMessage
事件。
您还可以在callPhantom()
的帮助下将数据发送到外部上下文,而不是记录它。请注意,并非所有内容都可以在contexts:
注意:
evaluate
函数的参数和返回值必须是一个简单的原始对象。经验法则:如果它可以通过JSON序列化,那就没关系了。闭包,函数,DOM节点等将不工作!
其他有用的事件处理程序是onError
,onResourceError
,onResourceTimeout
,以防仍有问题。
答案 1 :(得分:0)
我非常确定你需要在page.evaluate
中实际使用注入的JS(参见此处http://phantomjs.org/page-automation.html示例)。尝试:
function start() {
page.includeJs('https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js', function() {
console.log("got here");
page.evaluate(function() {
$.get("http://my-wonderful-site.com")
.done(function( data ) {
console.log("here!");
console.log(data);
phantom.exit();
});
});
});
}