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 上的回答。在這裡記錄一下,方便其他人找到。

解法是,你必須在 main process 裡面這樣設定:

    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 進行翻譯

留言