Node.js 文档未定义

Posted

技术标签:

【中文标题】Node.js 文档未定义【英文标题】:Node.js document is not defined 【发布时间】:2015-11-14 13:17:03 【问题描述】:

为什么 node.js 不能识别 document.GetElementById? 它说'ReferenceError:文档未定义'。 我能做什么?

ReferenceError: document is not defined
at Object.<anonymous> (C:\Users\Desktop\main.js:9:18)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:501:10)
at startup (node.js:129:16)
at node.js:814:3

【问题讨论】:

因为... node.js 没有像浏览器那样内置的 DOM。 @KevinB:您可以发布该答案以便可以接受吗?谢谢。 @Felix Remus 已经有了。 考虑到您正在尝试根据 ID 获取值而我只是在尝试做同样的事情,这个答案可能对您更有用***.com/questions/7977945/html-parser-on-node-js 改用window.document.getElementById 【参考方案1】:

从docs 只需将此注释添加到您的 .test.js 文件的顶部即可配置您的环境:

/**
* @jest-environment jsdom
*/

【讨论】:

【参考方案2】:

document 与 Web 浏览器中的 DOM(文档对象模型)相关。

然而,Node.js 不是浏览器环境。它是一个服务器环境,很像 php 或 Perl,因此,您无法访问浏览器的 DOM 或执行任何特定于浏览器托管 javascript 的操作。

最接近的方法是使用 browserify 之类的东西在客户端代码中包含 Node.js 模块。

【讨论】:

你能告诉我一些使用browserify的代码吗? 不,但他们有docs。请记住,客户端应用程序(DOM 可访问)的行为与服务器应用程序有很大不同。您将无法使用 browserify 在浏览器中启动服务器或执行任何与服务器相关的活动;它主要用于获取干净打包的 NPM 模块(例如 Moment.js 或 Lodash)并使其可用。 如果您要提供我们需要为某些库(例如 pdf.js)模拟浏览器 dom 服务器端的情况,我发现这个答案可能会更有用。 当然,但这不是问题所在。如果需要,请询问新的。【参考方案3】:

要理解答案,有必要了解:Javascript EngineBrowserNode.js之间的关系。

Javascript Engine:是 Javascript 编译器,将 JS 转换为机器码。例如,V8,就是一个很棒的。从技术上讲,V8 是用 C++ 开发的(您可以将其视为 C++ 程序)。

V8 实现了 ECMAScript,这是一种定义 JavaScript 特性和功能的 Javascript 语言标准。

但是 DOM 操作不是 ECMAScript 定义的。所以 V8 不支持。

浏览器:开发者可以在浏览器中使用document进行DOM操作,因为DOM操作是由浏览器提供的,例如:Chrome。

Chrome 也是由 C++ 开发的,V8(如前所述,也是由 C++ 开发的)嵌入到 Chrome 中以解释 Javascript。因此 Chrome 通过将 JS 命令和 C++ 实现绑定在一起来扩展或添加功能到 Javascript。

Nodejs:与 Chrome 不同,它是一个服务器端程序。但同样的是Nodejs是C++开发的,V8嵌入到Nodejs中来处理js。 Nodejs 以与 Chrome 类似的方式扩展了 Javascript 的功能。但是由于服务器端不需要处理 DOM,所以你不能在 Nodejs 中访问这些功能。

【讨论】:

【参考方案4】:npm install npm -g” 之后是“npm install -g typescript

这个命令帮我解决了这个问题

【讨论】:

【参考方案5】:

好的,简短的回答是您想访问仅在窗口和前端可用的 document 对象,不要忘记 document === window.document 您在服务器端和节点端...

所以永远不要在你的节点端尝试这样的事情,例如通过 ID 获取根元素会抛出错误,而是尝试从前端访问它:

document.getElementById('root');

会抛出错误:

ReferenceError: document is not defined
at Object.<anonymous> (C:\Users\Desktop\app.js:12:50)
at Module._compile (my.js:490:34)
at Object.Module._extensions..js (my.js:518:10)
at Module.load (my.js:555:42)
at Function.Module._load (my.js:610:12)
at Function.Module.runMain (my.js:701:10)
at startup (node.js:899:16)
at node.js:901:3

简短的回答是不要在 node.js 中使用 documentwindow 对象,因为它们在 node.js 中不可用...

在某些情况下使用 Domino 可以帮助访问 dom...

顾名思义,domino 的目标是在 Node 中提供 DOM。

与最初的 dom.js 项目相比,domino 并非旨在 运行不受信任的代码。因此,它不必隐藏其内部 一个代理外观,它不仅使代码更简单,而且更 高性能。

Domino 目前不使用任何和谐功能,例如代理或 WeakMaps,因此也可以在较旧的 Node 版本中运行。

欲了解更多信息,请访问here...

【讨论】:

这没有回答 这重申了问题。它不回答它【参考方案6】:

您可以使用JSDom 将 Dom 支持添加到 Node.js。要使变量全局化,您可以使用任一

GLOBAL.document = new JSDOM(html).window.document;

global.document = new JSDOM(html).window.document;

html 是您的网站字符串。

要使用 JSDom,请将其包含在您的项目中:

const jsdom = require("jsdom");
const  JSDOM  = jsdom;

或者在纯js中:

var jsdom = require("jsdom");
var JSDOM = jsdom.JSDOM;

我希望这能回答你的问题。

【讨论】:

以上是关于Node.js 文档未定义的主要内容,如果未能解决你的问题,请参考以下文章

Node.js socket.io.js 未找到或 io 未定义

Node.js 和 mysql 未定义函数

Node.js 中的错误“未定义窗口”

未定义模块名称 - node js

node.js ReferenceError:服务器未定义

Node.js + Express POST 请求返回未定义