有没有办法让 Electron 主进程脚本使用 `postMessage` 函数监听页面发布的消息?

Posted

技术标签:

【中文标题】有没有办法让 Electron 主进程脚本使用 `postMessage` 函数监听页面发布的消息?【英文标题】:Is there a way for a Electron main process script to listen on messages posted by a page with `postMessage` function? 【发布时间】:2020-09-15 00:11:09 【问题描述】:

我想在我的页面脚本中使用标准的 postMessage API 函数,该函数由 Electron 渲染器进程加载。

我想在渲染器进程脚本中坚持使用 Web API,因为该应用程序设计为在 Electron 和 Web 上(在用户首选的 Web 浏览器中)运行。我不想对 if(typeof electron != "undefined") ... 或类似的源代码阅读器征税。

有没有办法在 Electron 主进程脚本中侦听 postMessage 函数生成的消息或脚本窗口调度的事件?这将允许我在渲染器进程脚本中保持优雅的回退——如果未在 Electron 中运行,未处理的已发布消息也不会产生运行时错误。

到目前为止,我一直在使用preload property of the webPreferences object being passed to BrowserWindow constructor 加载以下预加载脚本,该脚本设置了我所追求的“通信桥”:

(() => 
    const electron = require("electron");
    addEventListener("message", ev => 
        switch(ev.data.type) 
            case "foobar":
                electron.ipcRenderer.send("foobar", ev.data.foobar); break;
        
    );
)();

然后我可以将postMessage( type: "foobar", foobar: foo: 1, bar: true , "*") 作为任何渲染器进程脚本的一部分,它基本上会导致渲染器进程将消息发送到主进程,上述设置由预加载脚本设置。

理想情况下,如果可能的话,我希望避免使用预加载脚本,但就像我说过的,我根本不想在渲染器进程脚本中使用任何 Electron API。如果我可以直接在主进程中收听渲染器脚本“窗口”发布的消息或由它调度的事件,那将消除我对预加载脚本的需要。但我不知道这是否可能,阅读文档给我的印象是我在兜圈子,或者我已经用尽了我的替代方案。

【问题讨论】:

postMessage 是进程内通信,不能跨进程传递。你应该使用 electron 内置的 ipc,或者其他任何不同的机制都可以进行进程间通信。 Electron 中已经有跨进程运行的 API。 postMessage 中没有任何固有的东西阻止它跨进程运行。事实上,如果我愿意,我可以重写预加载脚本中的函数,使其向主进程发送消息除了将消息发布到窗口(使用原始保存的postMessage值)——这将使它跨进程对话。但是我想知道我是否必须做这些事情,或者 Electron 是否已经公开了类似的机制,而无需我在渲染器进程中使用 Electron API。 是的,您通过包装 postmessage 以在内部调用 ipc 来使用这些进程间而不是 postmessage。 Electron exposes IPC,通过电子的 API - 并且电子永远不会为此目的覆盖普通渲染器 API。要使用 electron 的功能,您必须在渲染器进程中导入它,或者预加载,或者任何其他地方。 【参考方案1】:

不直接,但您可以在浏览器窗口上预加载脚本,该脚本在渲染器进程中接收该消息,并使用ipcRenderer.sendinvoke 复制该脚本。

【讨论】:

正如我在问题中概述的那样,这就是我已经在做的事情。 我的错,我读得太快了。但是,是的,这就是 AFAIK 的方法

以上是关于有没有办法让 Electron 主进程脚本使用 `postMessage` 函数监听页面发布的消息?的主要内容,如果未能解决你的问题,请参考以下文章

2electron进程

Electron 主进程和渲染进程

Electron 主进程和渲染进程

electron渲染进程与主进程通信

Electron应用结构

electron 使用