Electron 应用程序:如何使用 ipcRenderer.sendToHost()?

Electron app: How do you use ipcRenderer.sendToHost()?

在Electrondocumentation for the webview tag中,给出了下面的例子来展示渲染进程和webview中托管的网页之间的通信:

With sendToHost method and ipc-message event you can easily communicate between guest page and embedder page:

// In embedder page.
const webview = document.getElementById('foo')
webview.addEventListener('ipc-message', (event) => {
  console.log(event.channel)
  // Prints "pong"
})
webview.send('ping')

// In guest page.
const {ipcRenderer} = require('electron')
ipcRenderer.on('ping', () => {
  ipcRenderer.sendToHost('pong')
})

但是,在我的访客网页(在 webview 内)中,当我尝试 require('electron') 时,我得到 Uncaught ReferenceError: require is not defined,如文档中所示。

我还需要做些什么才能从访客网页请求 ipcRenderer 模块吗?

电子版:1.4.6

注意:我不确定这是否重要,但我的 webview 中的页面 运行 是从本地服务器提供的。在渲染器进程的顶级页面中,我执行类似以下操作:document.getElementById("webview").src = "http://localhost:1234/...";.

编辑: 看起来从本地服务器提供我的网页并没有改变任何东西。尝试使用静态 HTML 文件后,我遇到了同样的错误。看起来文档中的示例根本不起作用,或者我的理解有误。

// Simple foo.html somewhere on my computer
<script>
    const {ipcRenderer} = require('electron')
        ipcRenderer.on('ping', () => {
        ipcRenderer.sendToHost('pong')
    })
</script>

// In embedder page, in renderer process
document.getElementById("webview").src = "file://path/to/foo.html";

嵌入式页面的输出(在 webview 内): Uncaught ReferenceError: require is not defined

编辑

出于安全原因,在呈现器进程中使用 require 的首选方法是使用 preload 仅注入页面所需的最小节点集成。参见 Electron's security recommendations 的第 2) 点。 ipcRenderer:

的最小示例
// main.ts
const mainWindow = new BrowserWindow({
  webPreferences: {
    nodeIntegration: false,
    preload: './preload.js'
  }
})

mainWindow.loadURL('https://my-website.com')
// preload.js
const { ipcRenderer } = require('electron')

window.sendToElectron= function (channel) {
  ipcRenderer.send(channel)
}

您现在可以在您的网页中使用 window.sendToElectron("ping")

如果您在渲染器进程中使用 <webview>,您可以使用 <webview src="page.html" preload="./preload.js" /> 来获得相同的结果。所以,这就是我用来回答我原来的问题的方法,在 preload.js 中,我会在全局 window.

中注入一个调用 ipcRenderer.sendToHost("pong") 的函数

旧答案(不利于安全)

我错过了 webview 文档中的一个重要点。为了能够从嵌入在 webview 中的页面调用 require,您需要在 webview 标签上设置 nodeintegration 属性:

<webview id="webview" nodeintegration />