有没有办法让 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.send
或invoke
复制该脚本。
【讨论】:
正如我在问题中概述的那样,这就是我已经在做的事情。 我的错,我读得太快了。但是,是的,这就是 AFAIK 的方法以上是关于有没有办法让 Electron 主进程脚本使用 `postMessage` 函数监听页面发布的消息?的主要内容,如果未能解决你的问题,请参考以下文章