Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JQuery not getting included in PhantomJs

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.org", function(status) {

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

    var result;

    page.includeJs("https://ajax.googleapis.com/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.com/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.

like image 758
Himanshu Gahlot Avatar asked Jan 20 '15 21:01

Himanshu Gahlot


People also ask

What is the use of not in jQuery?

Given a jQuery object that represents a set of DOM elements, the .not() method constructs a new jQuery object from a subset of the matching elements. The supplied selector is tested against each element; the elements that don't match the selector will be included in the result.

Which elements are excluded from the filtered set in jQuery?

Elements for which the function returns true are excluded from the filtered set; all other elements are included. Note: When a CSS selector string is passed to .not (), text and comment nodes will always be removed from the resulting jQuery object during the filtering process.

Why is jQuery not working on my website?

In plain English, this error is trying to tell you that something on your site — may be a plugin — requires jQuery to function on your site. For some reason, when the browser tried to load the website and called for that specific jQuery, it was not available. This error can potentially shut down your site to visitors.

How do I know if jQuery is being loaded or not?

Look at the Network tab of your browser’s dev tools to see if jQuery is being loaded. This gives you one place to find a quick validation. Want to know how we increased our traffic over 1000%? Join 20,000+ others who get our weekly newsletter with insider WordPress tips!


1 Answers

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. Welcome 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.com/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);
like image 195
Artjom B. Avatar answered Oct 12 '22 22:10

Artjom B.