使用phantom.js中的jQuery发送跨域ajax请求

时间:2015-04-13 01:05:06

标签: javascript phantomjs

我正试图通过模拟它在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甚至没有执行。

2 个答案:

答案 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节点等将工作!

其他有用的事件处理程序是onErroronResourceErroronResourceTimeout,以防仍有问题。

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