为啥 Node.js 没有原生 DOM?

Posted

技术标签:

【中文标题】为啥 Node.js 没有原生 DOM?【英文标题】:Why doesn't Node.js have a native DOM?为什么 Node.js 没有原生 DOM? 【发布时间】:2011-10-03 04:30:09 【问题描述】:

当我发现 Node.js 是使用 V8 JavaScript 引擎构建的时,我想:

太好了,网页抓取会更容易 将像在浏览器中一样呈现,带有 支持 XPath 和任何 AJAX 调用的“本机”DOM 执行的页面。

    当它使用与 Chrome 相同的 javascript 引擎时,为什么没有原生 DOM? 为什么它没有在检索到的页面中运行 JavaScript 的模式? 关于 JavaScript 引擎与 Web 浏览器中的引擎,我有哪些不了解的地方?

非常感谢!

【问题讨论】:

试试phantomjs.org。 因为节点不是浏览器。 Node.js 不是浏览器这一事实是正确的,但这不是原因。 DOM 不是浏览器的东西,它是用于处理 XML/html/SGML 类文档的 API,仅此而已。 Node.js 没有它的原因仅仅是因为它们的主要范围是“后端”服务,而 DOM 解析显然不是他们认为必不可少的 API。此外,它与 JavaScript 也有关系——DOM API 是用 WebIDL 指定的,并且可以并且可以说最好将其实现为 Node.js 的本机模块。 【参考方案1】:

DOM 就是 DOM,JavaScript 实现只是一个单独的实体。 DOM 表示 Web 浏览器向 JavaScript 环境公开的一组工具。没有要求,但是任何特定的 JavaScript 运行时都将具有通过全局对象公开的任何设施。

Node.js 是一个独立的 JavaScript 环境,完全独立于网络浏览器。 Web 浏览器和 JavaScript 之间没有内在联系; DOM 不是 JavaScript 语言或规范或任何东西的一部分。

我在基于 Java 的 Web 服务器中使用旧的 Rhino 基于 Java 的 JavaScript 实现。该环境也与任何 DOM 无关。这是我自己的应用程序,它负责使用工具填充全局对象以执行我需要它能够执行的操作,它不是 DOM。

请注意,如果您想在 Node 项目中使用虚拟 DOM,可以使用 jsdom 之类的项目。由于其作为服务器端平台的本质,DOM 是 Node 可以不使用的工具,并且对于各种服务器应用程序仍然非常有意义。这并不是说 DOM 可能对某些人没有用处,只是它与进程控制、I/O、网络、数据库互操作等服务不在同一类服务中。

对于“为什么”这个问题,可能会有一些“官方”回答。在那里,但它基本上只是维护 Node 的人(现在的 Node 基金会)的业务。如果某个勇敢的开发人员决定 Node 应该默认提供一组模块来支持虚拟 DOM,并且成功地工作和工作并实现了这一点,那么 Node 拥有一个 DOM。 p>

【讨论】:

也没有“窗口”对象,fwiw。 这并没有解决为什么“它没有在检索到的页面中运行 JS 的模式?”。 C# 和 Java 可以独立于 Web 浏览器运行,但它们的标准库中都有 DOM 功能。它通常用于此目的。 形式的问题,“为什么 x 不做 y?”通常很难回答。 来自 php 背景,得知 NodeJs 不支持原生 DOM,我感到很震惊。当然,服务器环境不像浏览器那样需要 DOM,但这并不意味着原生 DOM 支持在任何服务器环境中都不是有价值的工具。它可用于 (1) 模板化、(2)、站点抓取、(3) 解析来自第三方 Web 服务的数据等。尤其是后一个功能对我来说对于现代 HTTP 服务器来说是必不可少的。 @JohnSlegers 我不否认你写的任何东西,但是在我编写软件的 36 年里,我从来没有想要服务器端 DOM 支持,只是作为一个数据点。【参考方案2】:

P.S:阅读这个问题时,我还想知道V8(node.js 建立在此之上)是否有 DOM

为什么当它使用与 Chrome 相同的 JS 引擎时,它没有原生 DOM?

但我搜索了谷歌并找到了Google's V8 page,它背诵了以下内容:

JavaScript 最常用于客户端脚本 浏览器,用于操作文档对象模型 (DOM) 对象 例如。然而,DOM 通常不是由 JavaScript 引擎,而是通过浏览器。也是如此 V8——谷歌浏览器提供了 DOM。然而,V8 确实提供了所有 ECMA 中指定的数据类型、运算符、对象和函数 标准。

node.js 使用V8 而不是Google Chrome

同样,为什么它没有在检索到的页面中运行JS的模式?

我也认为我们真的不需要那么糟糕。 Ryan Dahl 作为一个人(单一程序员)创建了 node.js。也许现在他(他的团队)会开发这个,但我已经对他产生的代码量感到非常惊讶(疯狂)。他想制作一个简单/高效的非阻塞库,我认为他在这方面做得非常好。

但话又说回来,另一位开发人员在https://github.com/tmpvar/jsdom 上创建了一个非常好的并积极开发的模块(今天)。

关于 Javascript 引擎与 网络浏览器? :)

这些是不同的东西,希望从上面的引用中可以清楚地看出。

【讨论】:

在这种情况下,Google Chrome 使用的是哪个“网络浏览器中的引擎”? @AndersonGreen,截至目前,Blink。【参考方案3】:

文档对象模型 (简称DOM)是一个HTML和XML文档的编程接口,它代表页面以便程序可以更改文档结构、样式和内容。 More on this subject.


客户端(浏览器)和服务器端(Node.js)的必要区别及其主要目标:

客户端:访问和显示网络信息 服务器端:提供稳定可靠的方式来传递网络信息

为什么Node.js默认没有DOM?

默认情况下,Node.js 没有访问权限,也不了解您自己浏览器中的实际 DOM。 Node.js 只是传递数据,您自己的浏览器将使用这些数据来处理和呈现整个网站,包括 DOM。服务器将数据提供给您的浏览器以供使用和处理。这是预期的方式。

您为什么不想访问 Node.js 中的 DOM?

使用 Node.js 访问浏览器的实际 DOM 完全超出了服务器的目标。您自己的浏览器的作用是显示来自服务器的数据。然而,这当然是可能的,并且有多种不同深度和种类的解决方案可以使用 AJAX 调用来预渲染、操作或更改 DOM。我们将看看未来的趋势会带来什么。

为什么要访问 Node.js 中的 DOM?

默认情况下,您不应该使用 Node.js 访问您自己的实际 DOM(至少它的一些数据)。基于多年的经验和知识,客户端和服务器端在角色、功能和责任方面是分开的。虽然有几种情况,但有充分的理由这样做:

收集使用数据(A/B 测试、UI/UX 效率和反馈) 无头测试(开发、自动化、网络抓取)

如何在 Node.js 中访问 DOM?

jsdom:纯 JavaScript 实现,适合测试您自己的 DOM/浏览器相关项目 cheerio:如果你喜欢/经常使用 jQuery,这是一个很好的解决方案 puppeteer:Google 自己使用 Google Chrome 提供无头测试的方式 自己的解决方案 (您可能的未来项目链接在这里)

虽然这些解决方案默认情况下不提供访问浏览器自己的实际 DOM 的方法,但您可以创建一个项目来发送关于您的 DOM 的某种形式的数据 到服务器,然后根据您的需要使用/渲染/操作该数据。

...是的,Web 抓取和 Web 开发在工具和实用程序方面变得更加复杂,并且在多个领域当然更容易。

【讨论】:

我觉得这个答案错过了在 node.js 标准库中拥有 DOM 解析器的意义。当您声明“这些解决方案默认情况下不提供访问浏览器自己的实际 DOM 的方法”时,它假定用户正在寻找对其浏览器的 DOM 的访问权限,或者“浏览器自己的实际 DOM”是“一个真正的 DOM”。任何提供 DOM 解析的库都是“实际 DOM”,无论它是否绑定到浏览器实例。【参考方案4】:

node.js 选择不将其包含在他们的标准库中。对于任何功能,都不​​可避免地要在全面性、可扩展性和可维护性之间进行权衡。

这并不意味着它没有潜在的用处。至少有一个用于 NodeJS 的 JavaScript DOM 实现(以及其他 CommonJS 实现)。

【讨论】:

【参考方案5】:

您似乎有一个错误的假设,即 V8 和 DOM 密不可分,事实并非如此。 DOM 实际上由 Webkit 处理,V8 不处理 DOM,它处理对 DOM 的 Javascript 调用。不要让这让您气馁,Node.js 在实时服务器市场中开辟了一个重要的利基市场,但不要让任何人告诉您它只是用于服务器。 Node 使得使用 JavaScript 构建几乎任何东西成为可能。

有可能做你所说的。例如,如果您确实需要访问 DOM,则有非常好的 jsdom 库,还有 node-htmlparser,还有一些非常好的抓取库可以利用这些优势,例如 apricot。

【讨论】:

【参考方案6】:

2018 年回答:主要是出于历史原因,但将来可能会改变。

从历史上看,很少在服务器上进行 DOM 操作。此外,正如其他答案所暗示的那样,JS stdlib 和 DOM 是单独的库 - 如果您使用的是节点,例如 Unix 脚本,那么 HTMLElementNodeList 等与此无关。

但是:服务器端 DOM 操作现在是交付网络应用程序的一个非常常见的部分。 Web 服务器需要了解页面的结构,并且如果被要求将资源呈现为 HTML,则需要提供反映 Web 应用程序初始状态的 HTML 内容。这意味着 Web 应用程序的加载速度比服务器简单地提供存根页面并让浏览器完成填充真实内容的工作要快得多。目前这是通过 JSDom 和类似方法完成的,但同样,node 内置了 RequestResponse 对象,将 DOM 函数作为 stdlib 的一部分进行维护将有助于完成这项任务。

【讨论】:

有人可能只是阅读了第一行并投了反对票。我认为说 Nodejs 没有实现 DOM 更准确。以“主要出于历史原因”开头并不是很准确“但是,DOM 通常不是由 JavaScript 引擎提供,而是由浏览器提供。” V8 intro @V8intro 答案一开始就已经说“JS stdlib 和 DOM 是单独的库”。这并不是“更准确地说 Nodejs 没有实现 DOM”。 - 我们已经知道 node 没有实现 DOM,问题是为什么。而这个(连同 MatthewFlaschen 的)是最准确的答案。【参考方案7】:

Javascript != 浏览器。 Javascript 作为一种语言不依赖于浏览器; node.js 只是用于服务器而非浏览器的 Javascript 实现。因此没有 DOM。

【讨论】:

当我想到 DOM 时,我会想到 DomDocument 接口、DomElement 接口和其他我们在 C、PHP、Javascript 和可能其他一些语言中已经习惯的接口。我还想到了一个允许将文本解析为 DOM 的解析器。这些是我已经习惯在 PHP 环境中使用的功能,而现在我已经在使用 NodeJs 进行第一次实验了。你问我用它做什么?好吧,我将它用于网络抓取、模板以及 - 最重要的是 - 用于网络服务!【参考方案8】:

如果您将 DOM 理解为“可从我的脚本立即访问的链接对象”,那么答案是“it does,但它与 Web 文档脚本中可用的一组对象非常不同”。主要原因是节点是“V8 的事件 I/O”,而不是“V8 的 HTML 树对象”

【讨论】:

当我想到 DOM 时,我会想到 DomDocument 接口、DomElement 接口和其他我们在 C、PHP、Javascript 和可能其他一些语言中已经习惯的接口。我还想到了一个允许将文本解析为 DOM 的解析器。这些是我已经习惯在 PHP 环境中使用的功能,而现在我已经在使用 NodeJs 进行第一次实验了。你问我用它做什么?好吧,我将它用于网络抓取、模板以及 - 最重要的是 - 用于网络服务!【参考方案9】:

Node 是一个运行时环境,它不像浏览器那样渲染 DOM。

【讨论】:

【参考方案10】:

因为没有 DOM。 DOM 代表Document Object Model。 Node 中没有文档,所以没有 DOM 来操作它。这绝对是浏览器的事情。

您可以使用像 cheerio 这样的库,不过它可以为您提供一些简单的 DOM 操作。

Node 是服务器级 JavaScript。它只是应用于基本系统 API 的语言,更像是 C++ 或 Java。

【讨论】:

【参考方案11】:

Node.js 用于服务器端 编程。服务器中没有要渲染的 DOM。

【讨论】:

当然可以,但是 V8 引擎不处理浏览器中的 DOM 吗?或者它是由浏览器创建的,然后“附加”(以某种方式)到 V8 引擎以允许 Javascript 与之交互? IE。为什么 Node.js 需要看似脆弱的库来查询 DOM,而我可以在 Chrome 中使用 V8 以快速可靠的方式进行查询? @PeterB 不,V8 引擎“处理 DOM”。 这是一个糟糕的答案。甚至 php 都有一个 DOM。 当我想到 DOM 时,我会想到 DomDocument 接口、DomElement 接口和其他我们在 C、PHP、Javascript 和可能其他一些语言中已经习惯的接口。我还想到了一个允许将文本解析为 DOM 的解析器。这些是我已经习惯在 PHP 环境中使用的功能,而现在我已经在使用 NodeJs 进行第一次实验了。你问我用它做什么?好吧,我将它用于网络抓取、模板以及 - 最重要的是 - 用于网络服务! DOM 在服务器上渲染,以快速加载 AJAX 应用程序。【参考方案12】:

似乎人们已经回答了“为什么”,但没有回答“如何”。一个快速的答案是如何在 Web 浏览器中公开一个文档对象(因此是 DOM ,文档对象模型)。在 Windows 上,此对象称为 document object。您可以参考此页面并查看它公开的用于处理 HTML 文档的方法,例如 createElement。我不使用 node.js 或者有一段时间没有进行 COM 编程,但我想你可以通过简单地调用 COM 对象IHTMLDocument3 在 node.js 中使用 DOM。当然,对于 Mac OS X 或 Linux 等其他平台,您可能必须使用他们的 OS api 中的某些内容。这应该允许您使用 DOM 轻松构建网页服务器端,或抓取传入的网页。

【讨论】:

【参考方案13】:

1) 拥有一个D ocument O bject M 模型是什么意思?没有可代表的文件。

2) 您大部分时间都没有检索页面。可以,但大多数 Node 应用程序可能不会。

3) 没有文档和浏览器,Javascript 只是另一种编程语言。所以你可能会问为什么 C# 或 Java 中没有 DOM

【讨论】:

在.NET 和Java 标准库中一个 DOM,它不属于 node.js 标准库是合理的。跨度> @MatthewFlaschen 这些是针对 XML 文档的,我不相信这是 OP 所说的。没有像浏览器环境中那样总能保证存在的无所不在的文档。 没错,如果只使用标准库,他将仅限于 XHTML。仅此一项就应该有价值。但是,有第三方库插入到这些 HTML 标准库中。 .NET 有 HtmlAgilityPack,Java 有 org.w3c.dom.html 子包,它扩展了 org.w3c.dom。没有人说有一份“无所不在的文件”。他特别询问了一个特定的场景,“网络抓取”。 当我想到 DOM 时,我会想到 DomDocument 接口、DomElement 接口和其他我们在 C、PHP、Javascript 和可能其他一些语言中已经习惯的接口。我还想到了一个允许将文本解析为 DOM 的解析器。这些是我已经习惯在 PHP 环境中使用的功能,而现在我已经在使用 NodeJs 进行第一次实验了。你问我用它做什么?好吧,我将它用于网络抓取、模板以及 - 最重要的是 - 用于网络服务!

以上是关于为啥 Node.js 没有原生 DOM?的主要内容,如果未能解决你的问题,请参考以下文章

node.js 1

Node.js - 为啥我的一些回调没有异步执行?

为啥我的 cpanel 没有在软件中显示设置 node.js 应用程序图标?

Node.js 并与像 Pidgin 这样的原生聊天交互?

为啥我的 node.js discord.js 机器人不发送文件? (没有错误)(可以发送消息)

为啥全新安装 node.js 和量角器会出现 `execvp` 错误没有这样的文件或目录?