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 进行翻译

评论