英文:
Electron webview's setWindowOpenHandler is not called at all when opening a new window
问题
My Electron(v22.3.6)应用程序使用<webview>标签。
此webview位于<webview>标签中的**'main.html'**渲染进程中。
而**'main.html'**由主进程中的mainWindow,一个BrowserWindow变量加载。
代码片段:
main.html
<webview id="wv" src="inner.html"></webview>
inner.html
<a href="https://example.com/" target="_blank">inner.html内的新窗口链接</a>
main.js
let winOpts = {
...
webPreferences: {
plugins: false,
nodeIntegration: false,
nodeIntegrationInWorker: false,
webviewTag: true,
sandbox: false, // 使用某些组件
enableRemoteModule: false,
contextIsolation: true,
disableBlinkFeatures: "Auxclick",
webSecurity: true,
preload: "preload.js"
}
};
mainWindow = new BrowserWindow(winOpts);
mainWindow.webContents.setWindowOpenHandler((handler) => {
//根本没有调用
return {
action: "allow"
};
});
mainWindow.loadFile("main.html");
问题:
当我点击'inner.html'内的链接<a href="newsite" target="_blank">link</a>时,
什么都不会发生。甚至DevTools中的'console'也没有显示任何内容。
'click'行为似乎不触发任何操作。
在上面的图中,
点击"Main Link"成功调用setWindowOpenHandler。
点击"Inner Link"什么都不做。既不会打开新窗口,也不会调用setWindowOpenHandler。
总结一下,在<webview>中的"_blank"目标链接在BrowserWindow中不起作用。setWindowOpenHandler未被调用。
英文:
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.
答案1
得分: 1
-
<webview>应该使用allowpopups,如<webview allowpopups></webview> -
在 'main process' 中,应该有一个监听器用于新生成的
webContents。然后,将setWindowOpenHandler附加到该监听函数中的webview的webContents上。
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只与webContents一起工作。- 应该从主进程中访问
webview的webContents。 - 在渲染进程中没有直接访问
webContents的方法,也不需要使用预加载脚本。 app.on('web-contents-created')可以在渲染进程中生成新的webview时检测到新的webContents,并且这个webContents负责监控新窗口链接(target="_blank" 或 window.open)。
无需任何存在安全漏洞的设置。
英文:
Found out how to:
-
<webview>should be withallowpopupslike<webview allowpopups></webview> -
In the 'main process', there should be a listener for newly generated
webContents. And, attach thesetWindowOpenHandlerto thewebview'swebContentsin 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:
setWindowOpenHandleronly works withwebContents.webview'swebContentsshould be accessed from the main process.- there is no direct way to access the
webContentsin renderer processes, and no need to use preload scripts for this. app.on('web-contents-created')can detect newwebContentswhen a newwebviewis generated in the renderer process, and the verywebContentsis responsible for monitoring new window links (target="_blank" or window.open).
No need for any security-vulnerable settings.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。



评论