Communicate with <webview> in Electron - electron

I have a <webview> in my Electron app. I'd like to have safe "foreign" communication, the way I would with an iframe through postMessage. So for example:
webview.executeJavaScript("window.parent.postMessage('all done!')");
Is my only choice for communication with this subwebview to turn on nodeIntegration so that I can use sendToHost? Turning on all of nodeIntegration just for this one feature seems like overkill.

You can access Electron APIs in the webview preload script, including IPC, even when nodeIntegration is disabled. Your preload script can inject functions into the global namespace that will then be accessible within the page loaded in the webview. A simple example:
webview-preload.js:
const { ipcRenderer } = require('electron')
global.pingHost = () => {
ipcRenderer.sendToHost('ping')
}
webview-index.html:
<script>
pingHost()
</script>
window-index.html:
<script>
const webview = document.getElementById('mywebview')
webview.addEventListener('ipc-message', event => {
// prints "ping"
console.log(event.channel)
})
</script>

Easiest way
Communication is
Note:
(main.js or app.js or background.js or process.js ) no need to pass (directly pass component to component),i succesffully implemented in electron:3.1.10
for print html webview.
Window To Webview
example1.html
<webview id="paper" style="width:300px;height:800px" src="file:///static/mywebview.html" nodeintegration></webview>
example1.js
var webview = document.getElementById("paper");
webview.send("ping",data);
getting data from mycomponent or window(i send directly form component)
mywebview.html
<!---what data you want show----!>
mywebview.js
const {
ipcRenderer
} = require('electron')
//data from window
ipcRenderer.on('ping', (e, data) => { console.log(data) })
webview to window
Webview to window(direct pass to component)
mywebview.js
ipcRenderer.sendToHost("readyCompanyInfo",data)
in my window eg i use vue (mycomponent.vue or mypage)
example1.html
const ipcRenderer = require("electron").ipcRenderer;
webview.addEventListener("ipc-message",(event)=>{
const {args,channel}=event;
if(channel=="readyCompanyInfo")
{
console.log(channel,args)
//here you can see data what u passed from webview to window
console.log(args[0])
}
})

Related

Unable retrieve page content using Playwright for certain JS pages (Node JS library)

For some of the below listed URLS, I am unable to fetch content of the page. I tried all options like load,dom,networkidle,commit and also tried using Chromium,WebKit and Firefox.
http://blog.naver.com/anupdown/221361918901
https://studio-sj.co/privacypolicy
https://www.leboncoin.fr/dc/cookies/
Code below
const { chromium } = require("playwright"); // Web scraper Library
let chromeBrowser = await chromium.launch({ headless: true }); // Chromium launch and options
let pageResponse = await page.goto("https://studio-sj.co/privacypolicy", {waitUntil: 'load', timeout: 30000 });
let content = await page.content();
Please note the content is inappropriate (i.e) HTML contains scripts.

In electron how to send custom header and value for every request?

I use electronjs for building a cross platform desktop application. I would like to send a custom header with a value for every request from electron. Initially in loadURL(), i could use extraHeaders to set the custom header. How to send it in all subsequent requests?
As recommended by the documentation, you should use session object and the method onBeforeSendHeaders:
const { session } = require('electron')
// Modify the user agent for all requests to the following urls.
const filter = {
urls: ['https://*.github.com/*', '*://electron.github.io']
}
session.defaultSession.webRequest.onBeforeSendHeaders(filter, (details, callback) => {
details.requestHeaders['User-Agent'] = 'MyAgent'
callback({ requestHeaders: details.requestHeaders })
})

Webframe executeJavascript pass down object

I am adding contextIsolation since I am loading remote content in my webview.
Using webFrame.executeJavascript(...) from inside a preload script, how do I pass down an un-serializable object to the inner webpage's context?
More concretely, here is my example:
preload.js:
// In the preload.js context
const { ipcRenderer, webFrame } = require('electron')
const ipc = {
send (data) {
ipcRenderer.sendToHost(...)
}
}
// Now I want to pass down ipc to the webpage's context
// This webpage is expecting window.myApp.ipc, so that it could use it like window.myApp.ipc.send(...)
webFrame.executeJavaScript(`window.myApp.ipc = ${ipc}`); // Doesn't work.
There's no way to send nonserializable object via executejavascript. If your preload script is for webview's, you can attach some object into window for global access.

Electron .ipcRenderer fires twice

I'm creating (for the first time) a small Mac only app using Electron.
I am trying to use ipcRenderer to communicate between my app menu and the content in the main BrowserWindow.
I have the menu set up as follows to send the message 'select-active':
const {Menu} = require('electron')
const electron = require('electron')
const app = electron.app
const BrowserWindow = electron.BrowserWindow
const template = [
{
label: 'Fonts',
submenu: [
{
label: 'Select All Acitve Fonts',
accelerator: 'Command+A',
click (item, focusedWindow) { if(focusedWindow) focusedWindow.webContents.send('select-active') }
},...
which I am then receiving as follows:
const ipcRenderer = require('electron').ipcRenderer;
ipcRenderer.on('select-active', function () {
console.log('SELECTED');
})
The problem I have is that every time the menu command is selected the message is logged twice in the console. Where am I going wrong?
How about using .once instead
ipcRenderer.once('select-active', function () {
console.log('SELECTED');
})
You are subscribing to ipcRenderer.on after React component rerendering (React calls your function every time it needs to get rendered version of it). Try to define the ipcRenderer.on event handler outside of React component function.
function yourFunction(){
return(){}
}
export default yourFunction;
ipcRenderer.send();
Place your ipcRenderer.send(); under the export default yourFunction;
It`s works for me!

Can't open Electron webview links with target = blank

I'm using Electron I have a webview which display an external website but I can't succeed to show the additional window normally opened by links on this site and which have target = _blank.
Mentions légales
I tried with
webpreferences="nativeWindowOpen=yes" allowpopups
But it didn't change.
With a webview, you can actually handle these on the main process quite easily.
Which also allows you to disable nodeIntegration should that be a requirement.
// Listen for web contents being created
app.on('web-contents-created', (e, contents) => {
// Check for a webview
if (contents.getType() == 'webview') {
// Listen for any new window events
contents.on('new-window', (e, url) => {
e.preventDefault()
shell.openExternal(url)
})
}
})
After digging into the documentation I wrote this code (code located in the renderer):
const {BrowserWindow} = require('electron').remote
..........
webview1.addEventListener('new-window', (e) => {
const protocol = require('url').parse(e.url).protocol
if (protocol === 'http:' || protocol === 'https:') {
//shell.openExternal(e.url)
let win = new BrowserWindow({width: 800, height: 600})
win.loadURL(e.url);
}
})
The line shell.openExternal(e.url) open the url of the link in a tab of the default browser.
And by using a new BrowserWindow, the new windows are Electron Window.

Resources