2015-01-20 14 views
5

Sto tentando di utilizzare jquery con phantomjs. Ho provato un esempio indipendente e ha funzionato bene. Ecco quello che ho fatto:JQuery non viene incluso in PhantomJs

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); 
} 

Ecco l'output che ho ottenuto:

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

Nel frammento di codice di cui sopra, ho usato setTimeout() sulla funzione valutare perché includeJs() eseguirebbe in modo asincrono e ha bisogno di tempo per caricare jquery. Se non utilizzo setTimeout() o non utilizzo un valore basso per il timeout, non funziona.

Tuttavia, quando provo lo stesso codice nella mia applicazione non funziona. Ecco quello che ho:

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); 
    } 

E questo è quello che vedo quando faccio funzionare la mia domanda:

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

La linea di log "carico jquery" non viene mai stampata e jQuery è mai caricato.

Ho provato a racchiudere la funzione evaluate() all'interno del callback di includeJs() ma non ha funzionato neanche (nessun log della console stampato).

Cosa potrebbe andare storto qui? Per favore fatemi sapere se dovrei fornire ulteriori informazioni.

risposta

7

Ecco perché page.includeJs ha un callback, quindi puoi inserire il codice che dipende da jQuery. Il callback viene chiamato quando il JavaScript di riferimento è già caricato. Benvenuti su un altro livello sulla strada dell'inferno del callback.

Ho sperimentato una volta però che questo non ha funzionato per qualche motivo. La soluzione alternativa era impostare una variabile globale nel callback includeJs e utilizzare waitFor per attendere che la variabile globale venisse impostata al di fuori del callback includeJs.

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); 
+0

questo è se si vuole ottenere in remoto ... e se la sua già sul server e si desidera solo per includere il jquery .min fiile ... useresti injectJs ... ma non funziona ancora per me – carinlynchin

+0

@Carine Non so cosa intendi per "server", ma 'page.injectJs' è utilizzabile solo quando il file è raggiungibile attraverso un percorso di file. Se non lo è, allora deve essere raggiungibile tramite un URI nel qual caso deve essere usato 'page.includeJs'. –

+0

Sì, lo so .. ma anche se ho page.injectJs ('jquery.min.js'), ho ancora l'errore "Impossibile trovare la variabile: $" – carinlynchin

0

ho solo problemi con questo, ma il mio errore è stato quello, ho provato phantom.injectJs, non page.injectJs (jerk). E poi, se è statussuccess, mettere

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

e cercare

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