使用来自 phantom.js 的 jQuery 发送跨域 ajax 请求
Send a cross-domain ajax request using jQuery from phantom.js
我正在尝试通过模拟它在 phantomjs 上执行的部分操作来测试 chrome 插件。
我想让 phantom 做的事情看起来非常简单,但我遇到了问题。我希望它访问某个网页,并在此页面的上下文中 运行 一个脚本,该脚本将向我的后端发送 ajax 请求并打印出响应。为了让我的生活更轻松,我希望 phantom 使用 jQuery 发送 ajax 请求。
这是我传递给 phantom 的脚本 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();
});
});
});
}
现在phantom就挂了,控制台输出为:
phantomjs test1.js --web-security=false
opened url
got here
也就是说,$.get
之前的 console.log 甚至没有执行。
我很确定您需要在 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();
});
});
});
}
PhantomJS 有两个上下文。内部上下文或页面上下文由 page.evaluate()
定义。它是沙盒的,无法访问外部定义的变量。所以,它不知道 phantom
是什么。同样,外部上下文不知道 $
是什么,因为 jQuery 是一个 DOM 库并被注入到页面中。您需要将 jQuery 请求包装在 page.evaluate()
.
中
另一件事是现在,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:
之间传递
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!
其他有用的事件处理程序是 onError
, onResourceError
, onResourceTimeout
,以防仍有问题。
我正在尝试通过模拟它在 phantomjs 上执行的部分操作来测试 chrome 插件。
我想让 phantom 做的事情看起来非常简单,但我遇到了问题。我希望它访问某个网页,并在此页面的上下文中 运行 一个脚本,该脚本将向我的后端发送 ajax 请求并打印出响应。为了让我的生活更轻松,我希望 phantom 使用 jQuery 发送 ajax 请求。
这是我传递给 phantom 的脚本 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();
});
});
});
}
现在phantom就挂了,控制台输出为:
phantomjs test1.js --web-security=false
opened url
got here
也就是说,$.get
之前的 console.log 甚至没有执行。
我很确定您需要在 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();
});
});
});
}
PhantomJS 有两个上下文。内部上下文或页面上下文由 page.evaluate()
定义。它是沙盒的,无法访问外部定义的变量。所以,它不知道 phantom
是什么。同样,外部上下文不知道 $
是什么,因为 jQuery 是一个 DOM 库并被注入到页面中。您需要将 jQuery 请求包装在 page.evaluate()
.
另一件事是现在,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:
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!
其他有用的事件处理程序是 onError
, onResourceError
, onResourceTimeout
,以防仍有问题。