【问题标题】:Electron - Why do we need to communicate between the main process and the renderer processes?Electron - 为什么我们需要在主进程和渲染器进程之间进行通信?
【发布时间】:2021-07-24 09:57:49
【问题描述】:

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

【问题讨论】:

  • 我添加了另一个答案,为您提供更多细节,帮助您理解为什么进程之间的通信很重要。

标签: javascript node.js electron ipc


【解决方案1】:

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

示例应用

我们希望我们的 Electron 应用程序是一个 Windows 资源管理器窗口,用户可以在其中创建、更新、删除或重命名文件或文件夹。我们创建了一个新的 Electron 应用程序并构建了我们的 ma​​inrenderer 进程。我们的 ma​​in 进程制作了 Electron 应用程序,我们将我们的逻辑放在 renderer 进程中以模拟资源管理器窗口。

在我们的renderer 过程中,我们使用fs 库创建调用来读取/创建/更新/删除新文件和文件夹。一切都很好。

还是

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

你没有保护你的应用

永远不要相信你的用户

因为您在应用程序中使用了 fs 库这一事实意味着任何用户都可以轻松 F12 进入您的应用程序,打开开发工具,并拥有 所有 fs 的访问权限在您的文件系统上。从本质上讲,由于您的应用程序缺乏安全性,您正在给坏人free rein of calculating numbers。如果您有兴趣,我已经写了有关此here 的更多详细信息。

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

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

  1. ma​​in 进程监听事件
  2. renderer 进程需要使用节点模块x,所以它发送一个使用它的请求(这是IPC)
  3. ma​​in 进程听到这个请求/事件,并使用节点模块 x 并返回结果并通过 IPC 将其发送回 renderer 进程
  4. renderer 进程获取结果并采取相应措施

我是secure Electron template 的作者,该secure Electron template 内置了此[IPC 消息],因此如果您有机会构建一个新应用程序,您不必白手起家。我最近去了reviewed the current best Electron templates to use,如果你刚开始,我会推荐其他模板。 (并非所有或最流行的模板一定是安全的,仅供参考)。

tl;博士

通过将对导入代码/节点库的访问隔离在用户可以访问的位置之外(即在 ma​​in 进程中),您可以在代码中进行安全检查,以免不要不小心让不良行为者访问您的操作系统。

【讨论】:

  • 是的。谢谢。这几天我一直在做一些小项目来了解这些东西。从长远来看,这将非常有帮助。仅供参考,我想我喜欢安全的电子模板,我肯定会在我未来的项目中使用它。
  • 我没有在您的示例中遇到安全问题。 Electron 应用程序没有比启动它的用户更多的权限。当然,他可以打开开发工具并使用 fs 删除文件。但他也可以在没有应用程序的情况下做到这一点。我在这里错过了什么?
  • @z80crew - 风险在于使用外部/远程代码(即 NPM 模块)或恶意内容。由于此代码不是您编写的,因此您无法 100% 确定实际执行的是什么。这就是为什么进程是分开的。 (如果我们确实编写了所有内容,那么我们就不需要单独的进程;这是我们可以提出的论点)。希望这会有所帮助!
【解决方案2】:

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

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

Electron 有两种类型的进程:Main 和 Renderer。

  • 主进程通过创建BrowserWindow 实例来创建网页。每个BrowserWindow 实例在其渲染器进程中运行网页。当 BrowserWindow 实例被销毁时,相应的 Renderer 进程也会终止。
  • 主进程管理所有网页及其对应的渲染器进程。

  • 渲染器进程只管理相应的网页。一个渲染器进程崩溃不会影响其他渲染器进程。
  • Renderer 进程通过 IPC 与 Main 进程通信,以在网页中执行 GUI 操作。由于安全问题和潜在的资源泄漏,直接从 Renderer 进程调用与 GUI 相关的原生 API 受到限制。

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

在该页面的下方:

Node.js API

注意:要从 Renderer 进程访问 Node.js API,您需要将 nodeIntegration 首选项设置为 true,并将 contextIsolation 首选项设置为 false。请注意,不建议security reasons 在任何加载远程内容的渲染器中访问 Node.js API。

因此,默认情况下,您的渲染器进程的功能受到限制,但您可以通过设置 nodeIntegration 首选项来消除该限制。但是,如果您的渲染器可能渲染远程内容,则会警告您不要这样做。 (有关更多信息,请参阅security reasons 链接。)

也就是说,如果您想做一些事情,比如读取或写入文件,但又不想在 Renderer 进程中启用 Node.js API 集成,则必须让 Renderer 向主进程(可以验证并限制范围)并让主进程使用 Node.js API 来读取/写入文件(同样,有限制)。

【讨论】:

  • 我不知道该怎么感谢你。这给出了我需要了解 IPC 的需求以及需要它的原因和时间的想法。真有见地。
猜你喜欢
  • 2021-12-04
  • 1970-01-01
  • 2016-12-08
  • 1970-01-01
  • 2017-06-01
  • 2017-10-07
  • 2018-01-05
  • 2020-04-09
  • 2018-05-05
相关资源
最近更新 更多