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

留言