Electron进程通信不能调用send的解法

806 阅读1分钟

一、背景

前几天用electron开发桌面小项目,本来直接网上找的示例直接用,却报了这个问题:electron Cannot read properties of undefined (reading 'send')。原因很简单,Electron出于安全考虑,不允许直接调用send往渲染进程发送消息。由于没必要退回到老版本,因此查了下网上的资料,找到了比较合适的方案。

二、解法

1、官方示例解法

文档:www.electronjs.org/zh/docs/lat…

代码:github.com/electron/el…

image-20240616215825495.png

这个方案的核心是使用 contextBridge API 来选择要从预加载脚本中暴露哪些 API,向渲染器进程暴露一个全局的 window.electronAPI 变量。

这个方案的的缺点是不好用,每个暴露的API都要过去注册一遍,有没有更简便的方法呢?

2、一个全栈大佬封装的工具

github.com/alex8088/el…

安装:npm i @electron-toolkit/preload

使用非常简单:

第一步引入preload

import { contextBridge } from 'electron'
import { electronAPI } from '@electron-toolkit/preload'if (process.contextIsolated) {
  try {
    contextBridge.exposeInMainWorld('electron', electronAPI)
  } catch (error) {
    console.error(error)
  }
} else {
  window.electron = electronAPI
}

第二步发消息

// Send a message to the main process with no response
window.electron.ipcRenderer.send('electron:say', 'hello')

// Send a message to the main process with the response asynchronously
window.electron.ipcRenderer.invoke('electron:doAThing', '').then(re => {
  console.log(re)
})

第三步监听

// Receive messages from the main process
window.electron.ipcRenderer.on('electron:reply', (_, args) => {
  console.log(args)
})

三、总结

古人说它山之石可以攻玉,又说尽信书不如无书,反正古人都对,哈哈哈哈。使用方法二避免了每次都去暴露API,提高了开发效率,建议使用。还有有个问题需要注意,不同的版本根据自己的情况适配下,不要盲目引用。比如下图,Electron 25版本使用的官方api监听消息也可以生效。

image-20240616221033696.png