从电子应用程序的 webview 中选择应允许哪些弹出窗口

Gor*_*vic 2 electron

我没有使用allowpopups属性来允许从电子应用程序中的 webview 打开弹出窗口,而是根据案例处理“新窗口”。

这是我的事件处理程序

content.addEventListener('new-window', function (e) {
  var url = e.url;
  var hostname = (new URL(url)).hostname.toLowerCase();

  if (hostname.indexOf('dropbox.com') !== -1 && url.indexOf('chooser') !== -1) {
    // this should open window but it doesnt
    return true;

  } else {
    content.loadURL(url);
    e.preventDefault();
  }  
});
Run Code Online (Sandbox Code Playgroud)

如您所见,触发此处理程序的事件是否具有 dropbox 的 url(例如),我希望电子允许按预期打开该窗口。

如果不是这种情况,我应该在电子应用程序中打开该网址。

...但这不起作用,当使用 dropbox url 时,我什么也没得到。关于我做错了什么的任何建议?

谢谢

Gor*_*vic 6

感谢蒂姆,我设法找到了解决这个问题的方法。

如果我们试图阻止打开新窗口或允许它们打开,如果我们试图在渲染器进程中处理它,'new-window' 就对我们没有用。如果我们尝试在渲染器进程中处理该事件,无论我们在该偶数处理程序中做什么,popup/window 都会打开。

解决方案是在主进程中处理该事件,但在此之前,我们需要将allowpopups和添加webpreferences="nativeWindowOpen=true"到我们的 webview。

allowpopups显然首先允许弹出窗口,并webpreferences="nativeWindowOpen=true"使用原生的 Chromium window.open,额外的好处是窗口打开和new-window事件按顺序发生,而不是异步发生。

webview 的代码应该是这样的:

<webview src="page.html" webpreferences="nativeWindowOpen=true" allowpopups></webview>
Run Code Online (Sandbox Code Playgroud)

之后在主进程中(通常main.js)我们可以处理我们想要允许在电子弹出窗口中打开的内容以及不允许的内容。首先我们必须正确处理 webview,然后我们才能处理new-window事件:

app.on('web-contents-created', function (webContentsCreatedEvent, contents) {
  if (contents.getType() === 'webview') {
    contents.on('new-window', function (newWindowEvent, url) {
      console.log('block');
      newWindowEvent.preventDefault();
    });
  }
});
Run Code Online (Sandbox Code Playgroud)

我在蒂姆的帮助下设法打乱了这个解决方案,并在此处阅读了关于拉取请求的评论https://github.com/electron/electron/pull/9568#issuecomment-306339926

希望这会对某人有所帮助。