admin管理员组

文章数量:1355617

I am trying to use jquery with phantomjs. I tried a standalone example and it worked fine. Here is what I did:

  var page = require('webpage').create();
  page.open("", function(status) {

    page.onConsoleMessage = function(msg) {
      console.log("message recvd: " + msg);
    };

    var result;

    page.includeJs(".10.1/jquery.min.js", function() {
      console.log("loading jquery");
    });

    setTimeout(function() {
      page.evaluate(function() {
        console.log("$(\"title\").text() -> " + $("title").text());
      });
    }, 1000);
 }

Here is the output I got:

loading jquery
message recvd: $("title").text() -> PhantomJS | PhantomJS

In the above code snippet, I have used setTimeout() on evaluate function because includeJs() would execute asynchronously and need some time to load jquery. If I do not use setTimeout() or use a small value for timeout, it doesn't work.

However, when I try the same code in my application it doesn't work. Here is what I have:

var baseSetup = function(guid, page, config, request, response) {
  /* enable the console output inside the callback functions */
  page.onConsoleMessage = function (msg) {
    console.log(guid + ": console msg: " + msg);
  };

  /* used for ignoring potential alert messages when evaluating js code */
  page.onAlert = function (msg) {
    console.log(guid + " (alert): alert msg: " + msg);
  };

  /* suppress the error messages */
  page.onError = function(msg, trace) {
    var msgStack = ['ERROR: ' + msg];
    if (trace && trace.length) {
      msgStack.push('TRACE:');
      trace.forEach(function(t) {
        msgStack.push(' -> ' +
        t.file +
        ': ' +
        t.line +
        (t.function ? ' (in function "' + t.function + '")' : ''));
      });
    }
    console.error(guid + ": " + msgStack.join('\n'));
  };
}

module.exports = function extractionDriver(responseFromUrl, responseToUser, page, request) {
  console.log(page.customHeaders['guid'] + ": extractionDriver, status = " + responseFromUrl.status);

  if(page.isLocalFile || responseFromUrl.status !== 0)
  {
    var viewportStr = page.customHeaders['viewportStr'];
    console.log(page.customHeaders['guid'] + ": Setting viewport size: " + viewportStr);
    var viewportObj = parseViewport(viewportStr);
    page.viewport = viewportObj;

    page.evaluate(function(w,h) {
      document.body.style.width = w + "px";
      document.body.style.height = h + "px";
    }, viewportObj.width, viewportObj.height);

    page.includeJs(".10.1/jquery.min.js", function() {
      console.log("loading jquery");
    });

    setTimeout(function() {
      page.evaluate(function() {
        console.log("$(\"title\").text() -> " + $("title").text());
      });
    }, 1000);
  }

And this is what I see when I run my application:

    d8db6045-a0e8-11e4-a619-6949593d958d: ERROR: ReferenceError: Can't find variable: $
TRACE:
-> phantomjs://webpage.evaluate(): 3
-> phantomjs://webpage.evaluate(): 4
-> phantomjs://webpage.evaluate(): 4

The log line "loading jquery" is never printed and jquery is never loaded.

I have tried wrapping up the evaluate() function inside the callback of includeJs() but that didn't work either (no console log printed).

What could be going wrong here? Please let me know if I should provide more information.

I am trying to use jquery with phantomjs. I tried a standalone example and it worked fine. Here is what I did:

  var page = require('webpage').create();
  page.open("http://www.phantomjs", function(status) {

    page.onConsoleMessage = function(msg) {
      console.log("message recvd: " + msg);
    };

    var result;

    page.includeJs("https://ajax.googleapis./ajax/libs/jquery/1.10.1/jquery.min.js", function() {
      console.log("loading jquery");
    });

    setTimeout(function() {
      page.evaluate(function() {
        console.log("$(\"title\").text() -> " + $("title").text());
      });
    }, 1000);
 }

Here is the output I got:

loading jquery
message recvd: $("title").text() -> PhantomJS | PhantomJS

In the above code snippet, I have used setTimeout() on evaluate function because includeJs() would execute asynchronously and need some time to load jquery. If I do not use setTimeout() or use a small value for timeout, it doesn't work.

However, when I try the same code in my application it doesn't work. Here is what I have:

var baseSetup = function(guid, page, config, request, response) {
  /* enable the console output inside the callback functions */
  page.onConsoleMessage = function (msg) {
    console.log(guid + ": console msg: " + msg);
  };

  /* used for ignoring potential alert messages when evaluating js code */
  page.onAlert = function (msg) {
    console.log(guid + " (alert): alert msg: " + msg);
  };

  /* suppress the error messages */
  page.onError = function(msg, trace) {
    var msgStack = ['ERROR: ' + msg];
    if (trace && trace.length) {
      msgStack.push('TRACE:');
      trace.forEach(function(t) {
        msgStack.push(' -> ' +
        t.file +
        ': ' +
        t.line +
        (t.function ? ' (in function "' + t.function + '")' : ''));
      });
    }
    console.error(guid + ": " + msgStack.join('\n'));
  };
}

module.exports = function extractionDriver(responseFromUrl, responseToUser, page, request) {
  console.log(page.customHeaders['guid'] + ": extractionDriver, status = " + responseFromUrl.status);

  if(page.isLocalFile || responseFromUrl.status !== 0)
  {
    var viewportStr = page.customHeaders['viewportStr'];
    console.log(page.customHeaders['guid'] + ": Setting viewport size: " + viewportStr);
    var viewportObj = parseViewport(viewportStr);
    page.viewport = viewportObj;

    page.evaluate(function(w,h) {
      document.body.style.width = w + "px";
      document.body.style.height = h + "px";
    }, viewportObj.width, viewportObj.height);

    page.includeJs("https://ajax.googleapis./ajax/libs/jquery/1.10.1/jquery.min.js", function() {
      console.log("loading jquery");
    });

    setTimeout(function() {
      page.evaluate(function() {
        console.log("$(\"title\").text() -> " + $("title").text());
      });
    }, 1000);
  }

And this is what I see when I run my application:

    d8db6045-a0e8-11e4-a619-6949593d958d: ERROR: ReferenceError: Can't find variable: $
TRACE:
-> phantomjs://webpage.evaluate(): 3
-> phantomjs://webpage.evaluate(): 4
-> phantomjs://webpage.evaluate(): 4

The log line "loading jquery" is never printed and jquery is never loaded.

I have tried wrapping up the evaluate() function inside the callback of includeJs() but that didn't work either (no console log printed).

What could be going wrong here? Please let me know if I should provide more information.

Share Improve this question edited Jan 20, 2015 at 21:32 Himanshu Gahlot asked Jan 20, 2015 at 21:18 Himanshu GahlotHimanshu Gahlot 2352 silver badges6 bronze badges 0
Add a ment  | 

2 Answers 2

Reset to default 7

That is why page.includeJs has a callback, so you can put the code that depends on jQuery in there. The callback is called when the referenced JavaScript is already loaded. Wele to another level on the road to the callback hell.

I experienced one time though that this didn't work for some reason. The workaround was to set a global variable in the includeJs callback and use waitFor to wait for the global variable to be set outside of the includeJs callback.

var _loadIndicator = false;
page.includeJs("https://ajax.googleapis./ajax/libs/jquery/1.10.1/jquery.min.js", function() {
  _loadIndicator = true;
});

waitFor(function check() {
  return _loadIndicator;
}, function onReady() {
  page.evaluate(function() {
    console.log("$(\"title\").text() -> " + $("title").text());
  });
}, 10000);

I just have troubles with this, but my mistake was that, i tried phantom.injectJs, not page.injectJs (jerk). And then, if status is success, put

page.injectJs('lib/jquery.min.js');

and try

page.evaluate(function(){
    console.log($("body").length);
});

本文标签: javascriptJQuery not getting included in PhantomJsStack Overflow