Using IPC layer and contextBridge to send data to renderer in Electron

Viewed 1919

I took out the irrelevant parts:

main.js

let window = null;
 app.on('ready', () => {
    window = new BrowserWindow({
        webPreferences: {
            nodeIntegration: false,
            contextIsolation: true,
            enableRemoteModule: false,
            preload: path.join(__dirname, "preload.js")
        }
    });

    window.loadFile('index.html')
        .then(() => {})
        .catch(err => console.log(err));
});

I have a timeout in main.js that calls

window.webContents.send('store-data', "MESSAGE");

preload.js

const {contextBridge,ipcRenderer} = require('electron');

contextBridge.exposeInMainWorld('electron', {
    storeData: (channel, data) => {
        ipcRenderer.on(channel, (event, data) => {
            return data;
        });
    }
});

index.html

window.electron.storeData('store-data', (data) =>{
    console.log(data);
});

This is working in that I get an object on the index.html side, but no data.

1 Answers

I obtained help from someone who works on Electron. Note: Communications between the IPC layer need to be carefully monitored and filtered to prevent security issues.

main.js

let window = null;

app.on('ready', () => {
    window = new BrowserWindow({
        webPreferences: {
            nodeIntegration: false,
            contextIsolation: true,
            enableRemoteModule: false,
            allowRunningInsecureContent: false,
            experimentalFeatures: false,
            preload: path.join(__dirname, "preload.js")
        }
    });

    window.loadFile('index.html')
        .then(() => {})
        .catch(err => console.log(err));
});

ipcMain.on('save', (event,text) => {
    setTimeout(()=>{
        event.sender.send('store-data', text);
    }, 1000) 
});

Please not the timeout and callback are for demonstrative purposes only. This is more of a proof of concept.

preload.js

const {contextBridge,ipcRenderer} = require('electron');

contextBridge.exposeInMainWorld('electron', {
    saveToElectron: (text) => ipcRenderer.send('save', text),
    storeData: (channel, func) => {
        ipcRenderer.on(channel, func);
    }
});

index.html's JS

    window.electron.storeData('store-data', (event,  data) =>{
        console.log("From Server: "+  data);
    });

This is mainly just sending a message from main to the rendering process...and attaching an event listener to listen for that message (in this example it's leading to saving a file).

Related