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 />
在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 />