My Electron (v22.3.6) app uses <webview>
tag.
This webview is located in the 'main.html' renderer process with <webview>
tag.
And the 'main.html' is loaded by mainWindow
, a BrowserWindow
variable, in the main process.
Snippets of the code:
main.html
<webview id="wv" src="inner.html"></webview>
inner.html
<a href="https://example.com/" target="_blank">New window link inside inner.html</a>
main.js
let winOpts = {
...
webPreferences: {
plugins: false,
nodeIntegration: false,
nodeIntegrationInWorker: false,
webviewTag: true,
sandbox: false, // to use some components
enableRemoteModule: false,
contextIsolation: true,
disableBlinkFeatures: "Auxclick",
webSecurity: true,
preload: "preload.js"
}
};
mainWindow = new BrowserWindow(winOpts);
mainWindow.webContents.setWindowOpenHandler((handler) => {
//NOT CALLED AT ALL
return {
action: "allow"
};
});
mainWindow.loadFile("main.html");
Problem:
When I click the link inside the 'inner.html', <a href="newsite" target="_blank">link</a>
,
nothing happens. Even 'console' in DevTools shows nothing.
The 'click' behavior seems to trigger nothing.
In the above figure,
clicking the "Main Link" successfully calls setWindowOpenHandler
.
clicking the "Inner Link" does nothing. Neither opening a new window nor calling setWindowOpenHandler
.
To sum up, "_blank" target link is not working inside <webview>
which is in a BrowserWindow
. setWindowOpenHandler
is not called.
Found out how to:
<webview>
should be with allowpopups
like <webview allowpopups></webview>
In the 'main process', there should be a listener for newly generated webContents
. And, attach the setWindowOpenHandler
to the webview
's webContents
in that listener function.
app.on('web-contents-created', (e, wc) => {
// wc: webContents of <webview> is now under control
wc.setWindowOpenHandler((handler) => {
return {action : "deny"}; // deny or allow
});
});
Explanation:
setWindowOpenHandler
only works with webContents
.webview
's webContents
should be accessed from the main process.webContents
in renderer processes, and no need to use preload scripts for this.app.on('web-contents-created')
can detect new webContents
when a new webview
is generated in the renderer process, and the very webContents
is responsible for monitoring new window links (target="_blank" or window.open).No need for any security-vulnerable settings.