You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 16:06:28