Electron中如何从渲染进程经预加载向主进程传参并返回响应?
解决Electron开启Context Isolation后无法传递参数调用主进程HTTPS请求的问题
你的代码存在几个关键问题,导致参数无法传递、请求结果无法正常返回,以下是针对性的修正方案:
核心问题梳理
- Preload脚本未传递参数:
ipcRenderer.invoke调用时未将渲染进程的参数传递给主进程 - 主进程IPC处理函数参数结构错误:
ipcMain.handle的第一个参数是event对象,自定义参数需要放在该对象之后 - 渲染进程未正确处理异步返回值:调用桥接函数时未返回Promise,也未使用
await获取异步结果 - URL拼接存在安全隐患:直接拼接参数可能导致URL编码错误,需用
URLSearchParams规范处理
修正后的代码
preload.js
补充参数传递逻辑,并返回ipcRenderer.invoke的Promise结果:
const { contextBridge, ipcRenderer } = require('electron'); let indexBridge = { getHttpReq: async (addressInput, startDateEpoch, endDateEpoch) => { // 将参数传递给主进程 return await ipcRenderer.invoke("getHttpReq", addressInput, startDateEpoch, endDateEpoch); } } contextBridge.exposeInMainWorld("indexBridge", indexBridge);
main.js
修正IPC处理函数的参数结构,用URLSearchParams安全拼接API地址,并补充完整的应用生命周期代码:
const { app, BrowserWindow, ipcMain } = require('electron'); const path = require("path"); const https = require('https'); const createWindow = () => { const win = new BrowserWindow({ height: 625, width: 1000, webPreferences: { preload: path.join(__dirname, 'preload.js'), } }); win.loadFile("index.html"); win.webContents.openDevTools(); }; // 修正参数结构:第一个参数为event,后续为自定义传递的参数 ipcMain.handle("getHttpReq", async (event, originalWallet, startDateEpoch, endDateEpoch) => { console.log("参数:钱包地址=" + originalWallet + " 起始时间戳=" + startDateEpoch + " 结束时间戳=" + endDateEpoch); return new Promise((resolve, reject) => { // 使用URLSearchParams处理参数,避免编码异常 const params = new URLSearchParams({ account: originalWallet, type: 'soltransfer', fromTime: startDateEpoch, toTime: endDateEpoch }); const url = `https://public-api.solscan.io/account/exportTransactions?${params}`; https.get(url, (resp) => { let data = ''; resp.on('data', (chunk) => { data += chunk; }); console.log("Solscan返回状态码:" + resp.statusCode); resp.on('end', () => { if (resp.statusCode !== 200) { console.log("Solscan错误详情:" + data); reject(new Error(`请求失败,状态码:${resp.statusCode}`)); return; } console.log("API返回数据:", data); resolve(data); }); }).on("error", (err) => { console.log("请求错误:" + err.message); reject(err); }); }); }) // 补充Electron应用生命周期逻辑 app.whenReady().then(() => { createWindow(); app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) createWindow(); }); }); app.on('window-all-closed', () => { if (process.platform !== 'darwin') app.quit(); });
renderer.js
让getHttpReq返回Promise,并在processInputWallet中使用await获取异步结果:
document.getElementById("myButton").addEventListener("click", processInputWallet); // 返回桥接函数的Promise,方便后续await处理 function getHttpReq(addressInput, startDateEpoch, endDateEpoch) { return window.indexBridge.getHttpReq(addressInput, startDateEpoch, endDateEpoch); } async function processInputWallet() { const addressInput = document.getElementById("solAddress").value; const startDate = new Date(document.getElementById("startDate").value); const endDate = new Date(document.getElementById("endDate").value); // 转为整数时间戳,匹配API要求 const startDateEpoch = Math.floor(startDate.getTime() / 1000); const endDateEpoch = Math.floor(endDate.getTime() / 1000); try { // await获取主进程返回的结果 const result = await getHttpReq(addressInput, startDateEpoch, endDateEpoch); console.log("渲染进程收到结果:", result); // 这里可添加数据渲染到页面的逻辑 } catch (err) { console.error("请求失败:", err); // 这里可添加错误提示逻辑 } }
内容的提问来源于stack exchange,提问作者user21036840
相关产品推荐
相关产品推荐

