How to allow popups in dynamically created webviews in Electron.js

Shawn Wang

如何在 Electron.js 中为动态创建的 webview 允许弹窗

原文由 Shawn Wang 发布,订阅该博客

我的 smol menubar 项目利用了 Electron 特有的 webview 标签来动态生成一组用于聊天的子浏览器窗口。过去几个月里,我一直遇到其中的 SSO 弹窗问题,具体来说就是弹窗完全不起作用,推测是因为 Electron 默认会屏蔽弹窗。

Electron 的 webview 有一个 allowpopups 属性,如果静态创建 webview,用它就能允许弹窗,但如果是动态添加的,这个属性就不起作用了。

const webview = document.createElement('webview');
webview.id = provider.webviewId;
webview.src = provider.url;
webview.setAttribute('allowpopups', 'true'); // adding dynamically...

我这里也加了:

import { ProviderInterface } from 'lib/types';

export default function Pane({ provider }: { provider: ProviderInterface }) {
    return (
        <div key={provider.paneId()} className="page darwin">
            <webview
                // @ts-ignore - we need this to be here or it will not show up in electron and then the allowpopups doesnt work
                allowpopups="true"
                id={provider.webviewId}
                src={provider.url}
                useragent={
                    provider.getUserAgent() ? provider.getUserAgent() : undefined
                }
            />
        </div>
    );
}

但这样会产生 TypeError: this._windowOpenHandler is not a function 错误。

图片

直接使用 setWindowOpenHandler 似乎也不起作用。

搜索了大约半小时后,我找到了这个 Stack Overflow 回答。在此记录一下,方便其他人查找。

解决方法是必须在主进程中进行设置:

    app.on('web-contents-created', (e, wc) => {
        // wc: webContents of <webview> is now under control
        wc.setWindowOpenHandler((handler) => {
                return {action : "allow"}; // deny or allow
        });
    });

PR 见此: https://github.com/smol-ai/menubar/pull/116/commits/89585ee94f27760e220efee5dc03e5480b8ca078

本文章由 muse-spark-1.2-contributor 进行翻译

评论