Electron - 为什么我们需要在主进程和渲染进程之间进行通信?

Electron - Why do we need to communicate between the main process and the renderer processes?

我对 electron js 比较陌生,在学习的过程中遇到了 IPC。据我了解,它用于主进程和一个或多个渲染器进程之间的通信。为什么我们需要在主进程和渲染器进程之间进行通信。我根本无法想象一个场景。任何人都可以帮助我理解我在这方面所缺少的理解吗?

警告:我还没有完成任何 Electron 工作。因此,请对以下所有内容持保留态度。

但我对这个问题很好奇,因为我天真地认为渲染器进程比它们(或者更确切地说,可以)更受限制。让我们从 the documentation:

的引述开始

Electron has two types of processes: Main and Renderer.

  • The Main process creates web pages by creating BrowserWindow instances. Each BrowserWindow instance runs the web page in its Renderer process. When a BrowserWindow instance is destroyed, the corresponding Renderer process gets terminated as well.
  • The Main process manages all web pages and their corresponding Renderer processes.

  • The Renderer process manages only the corresponding web page. A crash in one Renderer process does not affect other Renderer processes.
  • The Renderer process communicates with the Main process via IPC to perform GUI operations in a web page. Calling native GUI-related APIs from the Renderer process directly is restricted due to security concerns and potential resource leakage.

所以跳出的一个例子是:如果您需要创建一个新的 window 来响应用户操作怎么办?用户操作将被 BrowserWindow 中发生操作的渲染器进程看到,但只有主进程可以创建和管理网页。因此 window 的渲染器需要向 Main 发送一条消息,告诉它打开一个新页面(使用新的渲染器)。

在该页面的下方:

Node.js API

NOTE: To access the Node.js API from the Renderer process, you need to set the nodeIntegration preference to true and the contextIsolation preference to false. Please note that access to the Node.js API in any renderer that loads remote content is not recommended for security reasons.

所以默认情况下,您的渲染器进程在它们可以做的事情上是有限的,但您可以通过设置 nodeIntegration 首选项来消除该限制。但是如果您的渲染器可能渲染远程内容,您会被警告不要这样做。 (有关详细信息,请参阅 security reasons link。)

所以这意味着如果你想做一些像读取或写入文件的事情,但你不想在你的渲染器进程中启用 Node.js API 集成,你必须让渲染器向主进程发送消息(可以验证并限制范围)并让主进程使用 Node.js API 到 read/write 文件(同样,有限制).

Electron 应用程序非常强大,因为它们允许我们在其中使用 node。 Node 提供了许多 不同的库和工具,否则在编写 Web 应用程序时这些库和工具是不可用的。为了帮助理解为什么我们应该在 Electron 应用程序中使用两个进程,可以用一个例子来演示。

示例应用程序

我们希望我们的 Electron 应用程序成为 Windows 资源管理器 window,用户可以在其中创建、更新、删除或重命名文件或文件夹。我们创建一个新的 Electron 应用程序并构建我们的 mainrenderer 进程。我们的 main 进程制作 Electron 应用程序,我们将我们的逻辑放在 renderer 进程中以模仿资源管理器 window.

在我们的 renderer 过程中,我们使用 fs 库创建对 read/create/update/delete 新文件和文件夹的调用。一切顺利。

还是?

您决定发布您的应用程序,因为您会在市场上从中赚到大钱,但一周过去了,用户在使用您的应用程序后报告了奇怪的行为 .他们计算机上的应用程序无法运行,一些用户报告他们的计算机出现蓝屏 - 发生了什么事?

您没有保护您的应用程序

永远不要相信你的用户

因为您在您的应用程序中使用了 fs 库这一事实意味着任何用户都可以轻松地 F12 进入您的应用程序,打开开发工具,并拥有 所有 fs 对您的文件系统的访问权限。本质上,如果您有兴趣,您就是在给坏演员free rein of calculating numbers due to the lack of security in your app. I have written in more detail about this here

我们如何保护我们的应用程序?

一种更好地保护和防止用户在您的应用程序中使用节点或其他导入代码的方法是将它们分离到 main 进程中。不再让renderer进程直接使用导入的代码,改进后的进程是:

  1. main 进程侦听一个事件
  2. renderer进程需要使用节点模块x,所以它发送一个请求使用它(这是IPC)
  3. main 进程听到此 request/event,并使用节点模块 x 和 returns 结果并将其发送回 renderer 通过 IPC 处理
  4. 渲染器 进程获取结果并相应地采取行动

我是 secure Electron template that has this [IPC messaging] built in, so you don't have to work from nothing if you have the opportunity to build a new app. I recently went around and reviewed the current best Electron templates to use 的作者,如果您是新手,我会推荐其他模板。 (并非 所有 或最流行的模板都一定是安全的,仅供参考)。

tl;博士

通过将导入的 code/node 库的访问隔离在用户可以访问的地方之外(即在 main 进程中),您可以在您的代码,以免您不小心让不良行为者访问您的 OS.