2

I am completely new to Electron so please forgive me if I am doing this completely wrong.

Apparently for security reasons I need to use a contextBridge to communicate between the preload and renderer scripts and the main script. I could not find a clear example for how to set this up so I took the provided answer to this stack overflow question: How to use preload.js properly in Electron. However, when I try to access window.api.receive I get the error Cannot read property 'receive' of undefined. So my window.api is undefined but I can not figure out why.

I also tried to simply set window.isWorking = true in my preload.js script and tried to print it in my renderer script like I have seen others do, but this also just prints undefined.

I use the following code:
main.js

const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');

let win;

function createWindow() {
    win = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            contextIsolation: true,
            nodeIntegration: false,
            enableRemoteModule: false,
            preload: 'preload.js'
        }
    });

    win.loadFile('index.html');
}

app.whenReady().then(() => {
    createWindow();

    app.on('activate', () => {
        if (BrowserWindow.getAllWindows().length === 0) {
            createWindow();
        }
    });
});

app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
        app.quit();
    }
});

ipcMain.on("test", (event, args) => {
    console.log("received test request");
    win.webContents.send("test", "some data");
});

preload.js

import { ipcRenderer, contextBridge } from "electron";

contextBridge.exposeInMainWorld(
    "api", {
        send: (channel, data) => {
            let validChannels = ["test"];
            if (validChannels.includes(channel)) {
                ipcRenderer.send(channel, data);
            }
        },
        receive: (channel, func) => {
            let validChannels = ["test"];
            if (validChannels.includes(channel)) {
                ipcRenderer.on(channel, (event, ...args) => func(...args));
            }
        }
    }
);

window.isWorking = true;

renderer.js

console.log(window.isWorking); // prints undefined
window.api.receive("test", (data) => { // exception on trying to access window.api.receive
    console.log("data", data);
});
window.api.send("test", "some data");

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Hello World!</title>
    <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
    
</head>
<body style="background: white;">
    <h1>Hello World!</h1>
    <script src="renderer.js"></script>
</body>
</html>
Vincent Kenbeek
  • 583
  • 1
  • 5
  • 11

1 Answers1

-1

I think { contextIsolation: false; nodeIntegration: true } allows importing electron and allows to set window.something

So try writing:

win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
        contextIsolation: false,
        nodeIntegration: true,
        preload: 'preload.js'
    }
});