2013-12-17 11 views
5

Sono nuovo di nodejs, quello che sto cercando di fare è di esaminare tutti gli URL del mio sito (con javascript e jquery abilitati) e controllare che l'url contenga una determinata stringa.Jsdom errore di lancio per alcuni URL

Per fare questo sto usando jsdom, ma quando lancio lo script estrae solo alcune url e poi si blocca dando questo errore:

timers.js:110 
    first._onTimeout(); 
     ^
TypeError: Property '_onTimeout' of object [object Object] is not a function 
at Timer.listOnTimeout [as ontimeout] (timers.js:110:15) 

sicuramente c'è qualcosa che non va, ma non capisco dove. .

Questo è il mio script:

var request = require('request'); 
var jsdom = require('jsdom'); 

request({ uri: 'http://www.example.com' }, function (error, response, html) { 
    if (!error && response.statusCode == 200) { 

    var doc = jsdom.jsdom(html, null, { 
      features: { 
       FetchExternalResources : ['script'], 
       ProcessExternalResources : ['script'], 
       MutationEvents   : '2.0', 
      } 
    }); 

    var window = doc.createWindow(); 
    jsdom.jQueryify(window, "http://code.jquery.com/jquery-1.5.min.js", function() { 
     var $ = window.jQuery; 
     $('a').each(function(i, element){ 
      var a = $(this).attr('href'); 
      console.log(a); 
      if (a.indexOf('string') != -1) { 
       console.log('The winner: '+a); 
       //return a; 
      } 
     }); 
     window.close(); 
    }); 
    } 
}); 
+1

Sto avendo lo stesso problema, ma solo su alcuni URL. Non ho ancora determinato se si tratta di un errore generato dall'esecuzione effettiva di script nell'html raschiato o se si tratta di un errore interno nel codice jsdom. I segni puntano entrambi in questo momento :) –

+0

Ho fatto una richiesta di pull secondo il consiglio di @faridNouriNeshat: https://github.com/tmpvar/jsdom/pull/1186 –

risposta

3

questo è causa di qualche parte nella tua pagina stanno chiamando setTimeout/setInterval con una stringa che non è supportato in nodo e risulta in quell'errore.

Per sapere da dove proviene, suggerisco di richiedere il modulo longjohn (require('longjohn')) e di ottenere tracce di stack lunghe, che ti aiuteranno a trovare l'errore. Per esempio ho qualcosa di simile dal fare questo nel repl:

at listOnTimeout (timers.js:110:15) 
--------------------------------------------- 
    at startTimer (/home/alfred/repos/node_modules/jsdom/lib/jsdom/browser/index.js:75:15) 
    at DOMWindow.setTimeout (/home/alfred/repos/node_modules/jsdom/lib/jsdom/browser/index.js:124:50) 
    at file:///home/alfred/repos/repl:undefined:undefined<script>:1:1 
    at Contextify.sandbox.run (/home/alfred/repos/node_modules/jsdom/node_modules/contextify/lib/contextify.js:12:24) 
    at exports.javascript (/home/alfred/repos/node_modules/jsdom/lib/jsdom/level2/languages/javascript.js:5:14) 
    at define.proto._eval (/home/alfred/repos/node_modules/jsdom/lib/jsdom/level2/html.js:1523:47) 
    at /home/alfred/repos/node_modules/jsdom/lib/jsdom/level2/html.js:76:20 
    at item.check (/home/alfred/repos/node_modules/jsdom/lib/jsdom/level2/html.js:345:11) 

Se per caso che non ha funzionato per voi o non ti piace, allora vi suggerisco di modificare questo file jsdom: node_modules/jsdom/lib/jsdom/browser/index.js, funzione startTimer. Lanciare un errore lì se lo callback non era una funzione. Questo verrà generato ogni volta che viene eseguito il codice offensivo.

Nel caso in cui si stia utilizzando codice che non è possibile modificare (ad esempio da siti Web che non si possiedono, cosa che non lo suggerisco perché JavaScript javascript simile potrebbe essere utilizzato per attaccare la propria app), è possibile sovrascrivere DOMWindow.setTimeout/.setInterval per supportare gli argomenti stringa. Puoi anche aprire un problema per jsdom per avere questo opt-in.

Problemi correlati