You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何JSDOM中runScripts: 'dangerously'会改变window自有属性列表?

更新

我尚未明确原因,但runScripts: 'dangerously'参数引发了该问题。注释掉该参数后,第一个console.log会像浏览器一样输出1。


我为此问题的Node.js端创建了一个仓库。以下是完整的index.js文件:

import { JSDOM } from 'jsdom';

JSDOM.fromFile('template.html', {
    url: 'http://localhost',
    runScripts: 'dangerously',
    resources: 'usable',
    pretendToBeVisual: true,
}).then(({ window }) => {
    console.log(`Object.getOwnPropertyNames(window).filter((k) => k === "HTMLElement").length`, Object.getOwnPropertyNames(window).filter((k) => k === "HTMLElement").length);
    
    console.log(`window.HTMLElement`, window.HTMLElement);
    console.log(`Object.getOwnPropertyDescriptor(window, 'HTMLElement')`, Object.getOwnPropertyDescriptor(window, 'HTMLElement'));
    console.log(`Object.getPrototypeOf(window.constructor).name`, Object.getPrototypeOf(window.constructor).name);
});

注意该代码输出中的0:

Object.getOwnPropertyNames(window).filter((k) => k === "HTMLElement").length 0
window.HTMLElement [class HTMLElement extends Element]
Object.getOwnPropertyDescriptor(window, 'HTMLElement') {
  value: [class HTMLElement extends Element],
  writable: true,
  enumerable: false,
  configurable: true
}
Object.getPrototypeOf(window.constructor).name EventTarget

若在浏览器中运行相同的console.log语句,会输出1:

console.log(`Object.getOwnPropertyNames(window).filter((k) => k === "HTMLElement").length`, Object.getOwnPropertyNames(window).filter((k) => k === "HTMLElement").length);

console.log(`window.HTMLElement`, window.HTMLElement);
console.log(`Object.getOwnPropertyDescriptor(window, 'HTMLElement')`, Object.getOwnPropertyDescriptor(window, 'HTMLElement'));
console.log(`Object.getPrototypeOf(window.constructor).name`, Object.getPrototypeOf(window.constructor).name);

据我观察,这些属性的描述符一致,且两个window对象的原型名称也相同。我不清楚还有什么因素会导致此行为差异。

为何这段代码在JSDOM中的表现与浏览器不同?


补充信息

由于这可能是一个bug,我已在JSDOM仓库提交了GitHub Issue。

据我所知,template.html文件与本问题无关,但其内容如下:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>title</title>
  </head>
  <body>
    <p>Hello world</p>
  </body>
</html>

我使用的是jsdom 24.0.0和Node.js v20.10.0。

内容的提问来源于stack exchange,提问作者Daniel Kaplan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 01:17:57