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에는 webview를 정적으로 생성할 경우 이를 허용해 주는 allowpopups 속성이 있지만, 동적으로 추가하면 동작하지 않는다.

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를 단순히 사용해 봐도 동작하지 않는 것 같았다.

약 30분 정도 검색한 끝에 이 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 모델을 사용해 번역했습니다.

댓글