如何获取browserView内点击事件的结果并传递给Electron主进程
问题原因
你当前的写法无法获取到按钮点击的返回值:executeJavaScript 的.then回调仅能拿到你注入的JS代码同步执行的返回结果,而按钮点击属于异步触发的事件,注入代码执行完成时点击动作还未发生,因此不可能通过该方法的返回值拿到结果。
要实现从BrowserView的渲染进程向主进程传递异步事件数据,需要使用Electron的IPC(进程间通信)能力,实现方案如下:
实现方案
1. 主进程注册IPC监听事件
首先在主进程代码中注册事件监听器,用来接收渲染进程发送的点击数据,同时定义变量存储结果:
const { ipcMain } = require('electron') // 定义变量存储点击结果 let buttonClickResult = '' // 监听渲染进程发送的button-clicked事件 ipcMain.on('button-clicked', (event, data) => { buttonClickResult = data console.log('主进程已拿到点击结果:', buttonClickResult) // 后续可在此处处理对应业务逻辑 })
2. 修改注入的JS代码,点击时发送IPC消息
根据你BrowserView的安全配置,分为两种场景选择对应的写法:
场景1:未开启上下文隔离(contextIsolation: false)
直接修改你原来的executeJavaScript注入代码即可:
browserView.webContents.executeJavaScript(` const { ipcRenderer } = require('electron') let btn = document.createElement("button") btn.innerHTML = "Click Me" btn.addEventListener("click", function () { // 点击时向主进程发送事件和数据 ipcRenderer.send('button-clicked', 'Button is clicked') }) document.body.appendChild(btn) `)
场景2:开启上下文隔离(官方推荐的安全配置)
首先需要提前为BrowserView配置预加载脚本:
- 新建
preload.js预加载文件:
const { contextBridge, ipcRenderer } = require('electron') // 向渲染进程全局暴露通信方法 contextBridge.exposeInMainWorld('electronAPI', { sendClickData: (data) => ipcRenderer.send('button-clicked', data) })
- 创建BrowserView时指定预加载脚本配置:
const { BrowserView } = require('electron') const path = require('path') const browserView = new BrowserView({ webPreferences: { preload: path.join(__dirname, 'preload.js'), contextIsolation: true, // 开启上下文隔离 nodeIntegration: false // 关闭渲染进程node能力,更安全 } })
- 此时注入的代码修改为调用全局暴露的方法:
browserView.webContents.executeJavaScript(` let btn = document.createElement("button") btn.innerHTML = "Click Me" btn.addEventListener("click", function () { window.electronAPI.sendClickData('Button is clicked') }) document.body.appendChild(btn) `)
内容的提问来源于stack exchange,提问作者Alexei Romanov
相关产品推荐
相关产品推荐

