Jsdom 为某些 URL 抛出错误

Jsdom throwing error for some URLs

本文关键字:出错 错误 URL Jsdom      更新时间:2023-09-26

我是nodejs的新手,我想做的是扫描我网站的所有网址(启用了javascript和jquery)并检查网址是否包含给定的字符串。

为此,我使用的是jsdom,但是当我启动脚本时,脚本仅提取一些URL,然后崩溃并给出此错误:

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)

肯定有问题,但我不明白在哪里..

这是我的脚本:

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

这是因为在您的页面中的某个地方,他们使用节点不支持的字符串调用setTimeout/setInterval,这会导致该错误。

要找出它的来源,我建议只需要longjohn模块(require('longjohn')),您将获得长堆栈跟踪,它们将帮助您找到错误。例如,我在 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)

如果这对你不起作用,或者你不喜欢它,那么我建议你修改这个jsdom文件:node_modules/jsdom/lib/jsdom/browser/index.js,函数startTimer。如果callback不是函数,则在那里抛出错误。每当运行有问题的代码时,都会抛出。

如果你正在运行无法更改的代码(比如来自你不拥有的网站,我不建议这样做,因为像这样的外国javascript可以用来攻击你的应用程序),你可以覆盖DOMWindow.setTimeout/.setInterval以支持字符串参数。你也可以为 jsdom 打开一个问题,让这个选择加入。

相关文章: