Electron主进程向渲染进程发送Blob报错问题求助
问题原因及解决方法
报错原因
Electron的IPC通信(ipcMain.handle/ipcRenderer.invoke)依赖结构化克隆算法传递数据,但主进程中通过Node.js fetch获取的Blob对象,和渲染进程的浏览器环境Blob属于不同的JavaScript上下文实例,结构化克隆算法无法跨上下文直接克隆这类对象,因此抛出Error: An object could not be cloned错误。
解决方法
需要将Blob转换为IPC支持的可克隆格式(比如ArrayBuffer或Base64字符串),传递到渲染进程后再还原为Blob:
方法1:转换为ArrayBuffer传递
修改主进程代码:
ipcMain.handle('fetch_image', async (_ev, name) => { const res = await fetch(`....`); const blob = await res.blob(); // 将Blob转为ArrayBuffer const arrayBuffer = await blob.arrayBuffer(); return arrayBuffer; });
渲染进程调用时还原为Blob:
const arrayBuffer = await electron.getImage('test'); const blob = new Blob([arrayBuffer]); // 后续使用Blob,比如创建可访问的URL const imageUrl = URL.createObjectURL(blob);
方法2:转换为Base64字符串传递
主进程代码:
ipcMain.handle('fetch_image', async (_ev, name) => { const res = await fetch(`....`); const blob = await res.blob(); // 将Blob转为Base64格式 return new Promise((resolve) => { const reader = new FileReader(); reader.onloadend = () => resolve(reader.result); reader.readAsDataURL(blob); }); });
渲染进程直接使用或还原为Blob:
const base64Url = await electron.getImage('test'); // 直接赋值给img标签的src document.querySelector('img').src = base64Url; // 或者还原为Blob对象 const byteString = atob(base64Url.split(',')[1]); const arrayBuffer = new ArrayBuffer(byteString.length); const uint8Array = new Uint8Array(arrayBuffer); for (let i = 0; i < byteString.length; i++) { uint8Array[i] = byteString.charCodeAt(i); } const blob = new Blob([uint8Array]);
内容的提问来源于stack exchange,提问作者user19315471
相关产品推荐
相关产品推荐

