JSDOM未加载<script>标记随附的JavaScript

时间:2018-10-30 17:08:18

标签: javascript node.js jsdom

注意:该问题与其他现有问题并不重复,因为该问题未使用其他问题所做的 jsdom.env()函数调用。

文件 bar.js

  console.log('bar说:hello')
 

文件 foo.js

  var jsdom = require('jsdom')
var html ='<!DOCTYPE html>     
Foo
' var window = new jsdom.JSDOM(html).window window.onload = function(){   console.log('已加载窗口') }

当我运行 foo.js 时,我得到的输出。

  $节点foo.js
窗口加载
 

为什么 bar说:hello 输出没有出现?似乎未加载 bar.js 。如何让 jsdom 将文件加载到 script 标记中?

在昆汀回答答案后,问题解决了。这段代码有效:

  var jsdom = require('jsdom')
var html ='<!DOCTYPE html>     
Foo
' var window = new jsdom.JSDOM(html,{runScripts:“ dangerously”,resources:“ usable”})。window window.onload = function(){   console.log('已加载窗口') }

3 个答案:

答案 0 :(得分:2)

转到the JSDOM homepage

跳过标题,直到找到一个标记为Executing scripts

  

要在页面内启用执行脚本,可以使用   runScripts: "dangerously"选项:

const dom = new JSDOM(`<body>
  <script>document.body.appendChild(document.createElement("hr"));</script>
</body>`, { runScripts: "dangerously" });

// The script will be executed and modify the DOM:
dom.window.document.body.children.length === 2;
     

同样,我们强调仅在提供您知道的jsdom代码时才使用它   是安全的。如果您在任意用户提供的代码或以下代码上使用它   在互联网上,您实际上正在运行不受信任的Node.js代码,并且   您的机器可能受到威胁。

     

如果您要执行通过<script src="">包含的外部脚本,则还需要确保它们已加载它们。去做这个,   将选项resources: "usable"添加为described below

答案 1 :(得分:0)

鉴于我无法从上面的代码中复制基于url的解决方案...

残酷捆绑包:全部内联!

读取各种.js文件,并将它们作为字符串注入html页面。然后,像在普通导航器中一样等待页面加载。 这些库已加载到_window = new JSDOM(html, { options }).window;中,因此可用于您的节点脚本。

这很可能会阻止您拨打xhr电话,因此只能部分解决问题。

say-hello.js

// fired when loaded
console.log("say-hello.js says: hello!")
// defined and needing a call
var sayBye = function(name) { 
    var name = name ||'Hero!'; 
    console.log("say-hello.js says: Good bye! "+name)
}

main.js:

    const fs    = require("fs");
    const jsdom = require("jsdom");
    const { JSDOM } = jsdom;
    
    var NAME  = process.env.NAME; // variable from terminal

    var html = '<!DOCTYPE html><head></head><body><div>Foo</div></body>'
    var _window = new JSDOM(html, {
        runScripts: "dangerously",
        resources: "usable" }).window;
    /* ************************************************************************* */
    /* Add scripts to head ***************************************************** */
    var jsFiles = [
        'say-hello.js'
    ];
    var scriptsContent = ``;
    for(var i =0; i< jsFiles.length;i++){
        console.log(__dirname + '/'+ jsFiles[i])
      let scriptContent = fs.readFileSync( jsFiles[i], 'utf8');
      scriptsContent = scriptsContent + `
      /* ******************************************************************************************* */
      /* `+jsFiles[i]+` **************************************************************************** */
      `+scriptContent;
    };
    let scriptElement = _window.document.createElement('script');
    scriptElement.textContent = scriptsContent;
    _window.document.head.appendChild(scriptElement);


/* ************************************************************************* */
/* Run page **************************************************************** */
_window.document.addEventListener('DOMContentLoaded', () => {
    console.log('main says: DOMContentLoaded')
    // We need to delay one extra turn because we are the first DOMContentLoaded listener,
    // but we want to execute this code only after the second DOMContentLoaded listener
    // (added by external.js) fires.
    _window.sayBye(NAME); // prints "say-hello.js says: Good bye!"

  });

运行它:

NAME=John node main.js    # expects hello and good bye to john messages

来源:

答案 2 :(得分:0)

根据 source,使用 JSDOM 选项 url : file://${__dirname}/index.html 可以工作。如果您进行测试,请在此处报告结果。