Electron webview的setWindowOpenHandler在打开新窗口时根本不被调用。

huangapple go评论66阅读模式
英文:

Electron webview's setWindowOpenHandler is not called at all when opening a new window

问题

My Electron(v22.3.6)应用程序使用<webview>标签。

webview位于&lt;webview&gt;标签中的**'main.html'**渲染进程中。

而**'main.html'**由主进程中的mainWindow,一个BrowserWindow变量加载。

代码片段:

main.html

&lt;webview id=&quot;wv&quot; src=&quot;inner.html&quot;&gt;&lt;/webview&gt;

inner.html

&lt;a href=&quot;https://example.com/&quot; target=&quot;_blank&quot;&gt;inner.html内的新窗口链接&lt;/a&gt;

main.js

let winOpts = {
    ...
    webPreferences: {
        plugins: false,
        nodeIntegration: false,
        nodeIntegrationInWorker: false,
        webviewTag: true,
        sandbox: false, // 使用某些组件
        enableRemoteModule: false,
        contextIsolation: true,
        disableBlinkFeatures: &quot;Auxclick&quot;,
        webSecurity: true,
        preload: &quot;preload.js&quot;
    }    
};

mainWindow = new BrowserWindow(winOpts);
mainWindow.webContents.setWindowOpenHandler((handler) =&gt; {
    //根本没有调用
    return {
        action: &quot;allow&quot;
    };
});

mainWindow.loadFile(&quot;main.html&quot;);

问题:

当我点击'inner.html'内的链接&lt;a href=&quot;newsite&quot; target=&quot;_blank&quot;&gt;link&lt;/a&gt;时,
什么都不会发生。甚至DevTools中的'console'也没有显示任何内容。
'click'行为似乎不触发任何操作。

在上面的图中,
点击"Main Link"成功调用setWindowOpenHandler
点击"Inner Link"什么都不做。既不会打开新窗口,也不会调用setWindowOpenHandler

总结一下,在<webview>中的"_blank"目标链接在BrowserWindow中不起作用。setWindowOpenHandler未被调用。

英文:

My Electron (v22.3.6) app uses &lt;webview&gt; tag.

This webview is located in the 'main.html' renderer process with &lt;webview&gt; tag.

And the 'main.html' is loaded by mainWindow, a BrowserWindow variable, in the main process.

Snippets of the code:

main.html

&lt;webview id=&quot;wv&quot; src=&quot;inner.html&quot;&gt;&lt;/webview&gt;

inner.html

&lt;a href=&quot;https://example.com/&quot; target=&quot;_blank&quot;&gt;New window link inside inner.html&lt;/a&gt;

main.js

let winOpts = {
    ...
    webPreferences: {
        plugins: false,
        nodeIntegration: false,
        nodeIntegrationInWorker: false,
        webviewTag: true,
        sandbox: false, // to use some components
        enableRemoteModule: false,
        contextIsolation: true,
        disableBlinkFeatures: &quot;Auxclick&quot;,
        webSecurity: true,
        preload: &quot;preload.js&quot;
    }    
};

mainWindow = new BrowserWindow(winOpts);
mainWindow.webContents.setWindowOpenHandler((handler) =&gt; {
    //NOT CALLED AT ALL
    return {
        action: &quot;allow&quot;
    };
});

mainWindow.loadFile(&quot;main.html&quot;);

Problem:

When I click the link inside the 'inner.html', &lt;a href=&quot;newsite&quot; target=&quot;_blank&quot;&gt;link&lt;/a&gt;,
nothing happens. Even 'console' in DevTools shows nothing.
The 'click' behavior seems to trigger nothing.

Electron webview的setWindowOpenHandler在打开新窗口时根本不被调用。

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 &lt;webview&gt; which is in a BrowserWindow. setWindowOpenHandler is not called.

答案1

得分: 1

  1. &lt;webview&gt; 应该使用 allowpopups,如 &lt;webview allowpopups&gt;&lt;/webview&gt;

  2. 在 'main process' 中,应该有一个监听器用于新生成的 webContents。然后,将 setWindowOpenHandler 附加到该监听函数中的 webviewwebContents 上。

    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:

  1. setWindowOpenHandler 只与 webContents 一起工作。
  2. 应该从主进程中访问 webviewwebContents
  3. 在渲染进程中没有直接访问 webContents 的方法,也不需要使用预加载脚本。
  4. app.on('web-contents-created') 可以在渲染进程中生成新的 webview 时检测到新的 webContents,并且这个 webContents 负责监控新窗口链接(target="_blank" 或 window.open)。

无需任何存在安全漏洞的设置。

英文:

Found out how to:

  1. &lt;webview&gt; should be with allowpopups like &lt;webview allowpopups&gt;&lt;/webview&gt;

  2. 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(&#39;web-contents-created&#39;, (e, wc) =&gt; {
        // wc: webContents of &lt;webview&gt; is now under control
        wc.setWindowOpenHandler((handler) =&gt; {
            return {action : &quot;deny&quot;}; // deny or allow
        });
    });

Explanation:

  1. setWindowOpenHandler only works with webContents.
  2. webview's webContents should be accessed from the main process.
  3. there is no direct way to access the webContents in renderer processes, and no need to use preload scripts for this.
  4. app.on(&#39;web-contents-created&#39;) 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.

huangapple
  • 本文由 发表于 2023年5月8日 00:08:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76194986.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定