7

I've spent about an hour reading gist after repo after blog post, but can't seem to figure out how to do do this.

I have a BrowserWindow instance loading a URL (that I control), with nodeIntegration: false.

From the main process, I'd like to communicate with the rendered URL. I'm getting confused between preload scripts, BrowserWindow.send and executeJavascript paradigms.

The data I want to send is very large (eg. file uploads between 50kb and 10mb).

What's the best way to do this? Any any examples/tutorials you may know about would be helpful. Thanks!

onassar
  • 3,313
  • 7
  • 36
  • 58

2 Answers2

16

main.js

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

const window = new BrowserWindow({
  minWidth: 1200,
  minHeight: 700,
  autoHideMenuBar: true,
  resizable: true,
  show: false,
  scrollBounce: true,
  webPreferences: {
    preload: path.join(__dirname, 'preload.js'),
  }
})
window.webContents.loadURL('https://xxx.xxx.com') // load your web page
ipcMain.on('ping', (event, msg) => {
  console.log(msg) // msg from web page
  window.webContents.send('pong', 'hi web page') // send to web page
})

preload.js

const { ipcRenderer } = require('electron');
function init() {
  // add global variables to your web page
  window.isElectron = true
  window.ipcRenderer = ipcRenderer
}

init();

your web page

<script>
  if (window.isElectron) {
    window.ipcRenderer.send('ping', 'hello main')
    window.ipcRenderer.on('pong', (event, msg) => console.log(msg))
  }
</script>
Syntle
  • 5,168
  • 3
  • 13
  • 34
linxie
  • 1,849
  • 15
  • 20
  • Thanks for this. This is the way I went, and it's working great! – onassar May 08 '18 at 18:06
  • 3
    This is not considered secure, according to [https://electronjs.org/docs/tutorial/security]. See my answer here: https://stackoverflow.com/a/57656281/289203 – Luke H Aug 26 '19 at 10:42
2

Using preload script should work. You can use ipcRenderer to communicate with main process and expose it with simple API to renderer window. Simplest preload.js can look like:

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

let listener;
const bridge = {
   send: data => ipcRenderer.send('from-renderer', data),
   onMessage: callback => listener = callback 
}

ipcRenderer.on('to-renderer', (event, arg) => {
  if (listener) {
     listener(arg);
  } else {
     console.warn('No listener');
  }
});

window.bridge = bridge;

in renderer

window.bridge.send('Data to main process');
window.bridge.onMessage(payload => console.log('Data received', payload)) 

Please also take a look at this discussion to get more info.

udalmik
  • 7,838
  • 26
  • 40
  • 1
    This is not considered secure, according to [https://electronjs.org/docs/tutorial/security]. See my answer here: https://stackoverflow.com/a/57656281/289203 – Luke H Aug 26 '19 at 10:42