为什么 Node.js 没有原生 DOM?

IT技术 javascript node.js dom v8 headless-browser
2021-03-09 14:41:35

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

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

  1. 当它使用与 Chrome 相同的 JavaScript 引擎时,为什么它没有原生 DOM?
  2. 为什么它没有在检索到的页面中运行 JavaScript 的模式?
  3. 我对 JavaScript 引擎与 Web 浏览器中的引擎有何不了解?

非常感谢!

6个回答

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

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

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

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

对于“为什么?”这个问题,可能会有一些“官方”的答案。在那里,但这基本上只是维护 Node(现在是 Node 基金会)的人的事。如果一些勇敢的开发人员决定 Node 应该默认提供一组module来支持虚拟 DOM,并且成功运行并实现了这一点,那么 Node拥有一个 DOM。

@JohnSlegers 我不否认你写的任何东西,但在我写软件的 36 年里,我从不想要服务器端 DOM 支持,就像一个数据点。
2021-04-16 14:41:35
也没有“窗口”对象,fwiw。
2021-04-22 14:41:35
来自 PHP 背景,我很震惊地了解到 NodeJs 没有原生 DOM 支持。当然,服务器环境不像浏览器那样需要 DOM,但这并不意味着原生 DOM 支持在任何服务器环境中都不是有value的工具。它可以用于 (1) 模板,(2),站点抓取,(3) 解析来自第三方 Web 服务的数据等。尤其是后一个功能对我来说对于现代 HTTP 服务器来说似乎是必不可少的。
2021-05-10 14:41:35
这并没有解决为什么“它没有在检索到的页面中运行 JS 的模式?”。 C#Java可以独立于 Web 浏览器运行,但它们的标准库中都具有 DOM 功能。它经常用于此目的。
2021-05-15 14:41:35
形式的问题,“为什么 x 不做 y?” 一般很难回答。
2021-05-15 14:41:35

PS:在阅读这个问题时,我还想知道V8(node.js 是在此基础上构建的)是否有一个 DOM

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

但是我搜索了谷歌并找到了谷歌的 V8 页面,其中背诵了以下内容:

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

node.js 使用V8而不是Google Chrome.

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

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

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

我对 Javascript 引擎与 Web 浏览器中的引擎有何不了解?:)

这些是不同的事情,希望从上面的引文中可以清楚地看出。

在这种情况下,Google Chrome 使用哪个“网络浏览器中的引擎”?
2021-04-23 14:41:35
@AndersonGreen,截至目前,Blink
2021-05-12 14:41:35

文档对象模型 (DOM简称)是一个编程接口HTML和XML文件以及它所代表的页面,这样的程序可以改变文档结构,风格和内容。更多关于这个主题。


客户端(浏览器)和服务器端(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:谷歌自己的方式使用谷歌浏览器提供无头测试
  • 自己的解决方案 (您可能的未来项目链接在这里)

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

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

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

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

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

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

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