jsdom 不在本地文件系统上获取脚本

jsdom does not fetch scripts on local file system

我是这样构造的:

var fs = require("fs");
var jsdom = require("jsdom");

var htmlSource = fs.readFileSync("./test.html", "utf8");
var doc = jsdom.jsdom(htmlSource,  {
    features: {
    FetchExternalResources   : ['script'],
    ProcessExternalResources : ['script'],
    MutationEvents           : '2.0'
},
    parsingMode: "auto",
    created: function (error, window) {
        console.log(window.b); // always undefined
    }
});

jsdom.jQueryify(doc.defaultView, 'https://code.jquery.com/jquery-2.1.3.min.js', function() {

    console.log( doc.defaultView.b ); // undefined with local jquery in html
});

html:

<!DOCTYPE HTML>
<html>
<head></head>
<body>
<script src="./js/lib/vendor/jquery.js"></script>
<!-- <script src="http://code.jquery.com/jquery.js"></script> -->
<script type="text/javascript">

var a = $("body"); // script crashes here
var b = "b";

</script>
</body>
</html>

只要我用 http 源替换 html 中的 jquery 路径,它就可以工作。本地路径完全相对于 shell / 实际节点脚本的工作目录。老实说,我什至不知道为什么我需要 jQueryify,但是如果没有它,window 永远不会有 jQuery,即使有它,它仍然需要 [=] 中的 http 源18=] 文档。

您没有告诉 jsdom 您网站的基础在哪里。它不知道如何解析您给它的(相对)路径(并尝试从默认 about:blank 解析,但这是行不通的)。这也是它使用绝对 (http) URL 的原因,它不需要知道从哪里解析,因为它是绝对的。

你需要在你的初始化中提供 url 选项来给它基础 url(应该看起来像 file:///path/to/your/file)。

jQuerify 只是插入一个带有您给它的路径的脚本标记 - 当您在 html 工作中获得引用时,您不需要它。

我发现了。我会将 Sebmasters 的答案标记为已接受,因为它解决了两个问题之一。另一个原因是我没有正确地等待加载事件,因此外部脚本之外的代码还没有被解析。

我需要做的是在 jsdom() 调用后向 doc.defaultView 添加一个负载监听器。

它在使用 jQuerify 时起作用的原因很简单,因为它为嵌入脚本的加载创建了足够的超时时间。

当 jquery 库到 jQueryify 函数的完整相对路径时,我遇到了同样的问题。我通过提供完整路径解决了这个问题。

const jsdom = require('node-jsdom')
const jqueryPath = __dirname + '/node_modules/jquery/dist/jquery.js'

window = jsdom.jsdom().parentWindow

jsdom.jQueryify(window, jqueryPath, function() {
    window.$('body').append('<div class="testing">Hello World, It works')
    console.log(window.$('.testing').text())
})