我正在尝试升级我的Electron应用程序,没有节点集成和上下文隔离。我正在将文件保存代码从渲染器移动到主进程。但是,我无法将blob传输到主进程。
错误消息为:
Uncaught (in promise) Error: An object could not be cloned.
字符串
main.js
const {app, BrowserWindow, dialog, ipcMain } = require('electron');
const path = require("path");
const fs = require("fs");
if (require('electron-squirrel-startup')) return app.quit();
try {require('electron-reloader')(module);} catch (_) {}
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win;
async function createWindow() {
// Create the browser window.
win = new BrowserWindow({
width: 1024,
height: 768,
webPreferences: {
preload: path.join(__dirname, "preload.js") // use a preload script
},
autoHideMenuBar: true,
icon: __dirname + '/icons/icon.icns'
});
// and load the index.html of the app.
win.loadFile('index.html')
// Open the DevTools.
win.webContents.openDevTools()
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
createWindow();
ipcMain.handle('dialog', (event, method, params) => {
return dialog[method](params);
});
ipcMain.handle('getPath', () => {
app.getPath('documents');
});
ipcMain.handle('writeFile', (event, filepath, blob) => {
var message = {};
fs.writeFile(filepath, blob, err => {
if (err) {
message.text = err;
message.title = 'Error Saving Table';
} else {
message.text = filepath;
message.title = 'Table saved to';
}
});
return message;
});
});
型
preload.js
const {
ipcRenderer,
contextBridge
} = require("electron");
contextBridge.exposeInMainWorld('electron', {
openDialog: (method, params) => ipcRenderer.invoke('dialog', method, params),
getPath: () => ipcRenderer.invoke('getPath'),
writeFile: (filepath, blob) => ipcRenderer.invoke('writeFile', filepath, blob)
});
型
renderer.js
function exportToExcelFile(tableID, anchorID, exportFilename) {
let format = 'xlsx';
let anchor = $$('#' + anchorID + '-' + format);
ExcellentExport.convert({
anchor: anchor[0],
filename: exportFilename,
format: format
}, [{
name: 'Sheet1',
from: {
table: $$('#' + tableID)[0]
}
}]);
// Get path, open save dialog and save file
window.electron.getPath()
.then((appDataPath) => {
const dialogConfig = {
filters: [{
name: 'Excel',
extensions: ['xlsx']
}],
defaultPath: appDataPath + '/' + exportFilename
};
electron.openDialog('showSaveDialogSync', dialogConfig).then(
filepath => {
if (filepath !== undefined) {
console.log(anchor.attr('href'));
fetch(anchor.attr('href'))
.then(res => res.blob())
.then(blob => {electron.writeFile(filepath, blob);
})
.then(message => {app.dialog.alert(message.text, message.title);
})
}
}
);
})
.catch(result => console.log(result));
}
型
1条答案
按热度按时间34gzjxbg1#
你不能通过IPC将一个Blob从渲染器发送到main,在此之前你必须将它转换为ArrayBuffer。
为了能够将ArrayBuffer写入文件系统,一旦你在main上收到它,你必须将它转换为Node.js的全局Buffer。
个字符
(you也可以使用FileReader API将ArrayBuffer直接从渲染器进程转换为Buffer,然后将其发送到main,因此可以直接写入文件系统)