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

jen*_*ins 6 ipc webview electron

在webview 标签的Electron文档中,给出了以下示例来展示如何在渲染器进程和 webview 中托管的网页之间进行通信:

使用 sendToHost 方法和 ipc-message 事件,您可以轻松地在访客页面和嵌入器页面之间进行通信:

// 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')
})
Run Code Online (Sandbox Code Playgroud)

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

我还需要做些什么才能从访客网页请求 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";
Run Code Online (Sandbox Code Playgroud)

嵌入页面的输出(在 web 视图内): Uncaught ReferenceError: require is not defined

jen*_*ins 4

编辑

出于安全原因,在渲染器进程中使用的首选方法requirepreload仅注入页面所需的最小节点集成。请参阅Electron 安全建议的第 2) 点。一个最小的例子ipcRenderer

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

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

window.sendToElectron= function (channel) {
  ipcRenderer.send(channel)
}
Run Code Online (Sandbox Code Playgroud)

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

<webview>如果您在渲染器进程内部使用,则可以使用它<webview src="page.html" preload="./preload.js" />来实现相同的结果。所以,这就是我用来回答我原来的问题的方法,在里面preload.js我会注入一个调用ipcRenderer.sendToHost("pong")全局window.


旧答案(不利于安全)

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

<webview id="webview" nodeintegration />