Electron中ipcMain.handle()无法向ipcRenderer.invoke()返回值求助
Electron + React 凭据存储读取问题
我被这个问题困扰2天,查阅了Electron API文档及各类网站,现求助:
相关代码文件
main.ts(非完整代码)
app.whenReady().then(() => { ipcMain.on("set-credentials", (event, args: object) => { encryptedCredentials = safeStorage.encryptString(JSON.stringify(args)); }); ipcMain.handle("get-credentials", async (event, args: null) => { const decryptedCredentials = await JSON.parse( safeStorage.decryptString(encryptedCredentials) ); return decryptedCredentials; }); createWindow(); });
preload.ts(完整代码)
import { ipcRenderer, contextBridge } from "electron"; contextBridge.exposeInMainWorld("electronAPI", { setStoredCredentials: async (args: object) => await ipcRenderer.send("set-credentials", args), getStoredCredentials: () => { ipcRenderer.invoke("get-credentials"); }, });
Login.tsx(非完整代码)
const setStoredCredentials = async (e: any, service: string) => { e.preventDefault(); window.electronAPI.setStoredCredentials({ service, username: e.target[0].value, password: e.target[1].value, }); setTimeout(() => { window.electronAPI.getStoredCredentials().then( (data: object) => { console.log(data); } // 测试用 ) }, 1000) };
补充说明:该应用基于React开发;main.ts中返回值前执行console.log()能正常输出目标值;encryptedCredentials变量声明为let encryptedCredentials: Buffer;。之前尝试过用ipcMain.on搭配ipcRenderer.sendSync及event.returnValue,要么出现相同错误,要么返回undefined。
当前错误
caught TypeError: Cannot read properties of undefined (reading 'then')
问题修复方案
1. 修复preload.ts的Promise返回问题
ipcRenderer.invoke本身返回Promise,但你的getStoredCredentials函数没有返回这个Promise,导致调用时返回undefined,无法调用.then()。修改后代码:
import { ipcRenderer, contextBridge } from "electron"; contextBridge.exposeInMainWorld("electronAPI", { setStoredCredentials: (args: object) => ipcRenderer.send("set-credentials", args), // send是单向同步调用,无需async/await getStoredCredentials: () => { return ipcRenderer.invoke("get-credentials"); // 必须返回invoke的Promise }, });
2. 移除main.ts中不必要的await
JSON.parse是同步方法,添加await无意义,直接去掉:
ipcMain.handle("get-credentials", (event, args: null) => { const decryptedCredentials = JSON.parse( safeStorage.decryptString(encryptedCredentials) ); return decryptedCredentials; });
3. 优化Login.tsx的调用逻辑
无需使用setTimeout,直接用async/await处理异步调用:
const setStoredCredentials = async (e: any, service: string) => { e.preventDefault(); window.electronAPI.setStoredCredentials({ service, username: e.target[0].value, password: e.target[1].value, }); // 直接异步获取,无需延迟 const data = await window.electronAPI.getStoredCredentials(); console.log(data); };
额外提示
- 确保
encryptedCredentials在main.ts中正确初始化,避免首次调用get-credentials时因变量未定义报错。 ipcRenderer.send是单向通信,不需要包裹async/await,可简化setStoredCredentials的定义。
内容的提问来源于stack exchange,提问作者Dan149
相关产品推荐
相关产品推荐

