电子:webview不会从新创建的窗口

时间:2016-07-26 12:58:33

标签: javascript webview chromium electron new-window

我的桌面应用程序可以像简单的浏览器一样工作。它包含显示网页的webview选项卡。

有些网站有social sign-in选项。我真的需要它可供我的用户使用。

在通过Facebook登录时,一般浏览器(例如chrome)会创建带有社交授权表单的新窗口。提交此表单后,新窗口关闭,父窗口收到回调代码,重新加载并为您登录。<​​/ p>

在我的应用程序中,当您尝试执行相同操作时,包含该网页的webview会创建具有相同身份验证表单的新BrowserWindow。此时一切正常。提交表单时,新窗口关闭,但之后没有任何反应。父窗口没有收到任何回调,根本不会触发应该运行的代码。或者可能已收到,但未触发,因为如果我重新加载页面,则表明我已登录。

根据electron documentation&lt; webview&gt;在比渲染器进程独立的进程中运行。所以我认为当新窗口关闭时,回调是由父BrowserWindow(渲染器进程)接收的,而不是在webview框架中完全运行。

在搜索不同来源的解决方案时,我发现这个问题也与window.opener有关,在最早的电子版本中并没有完全支持。但根据github完整窗口上的issue#1865,如果我通过window.open方法打开窗口,现在可以使用.opener支持。

为了完成这项工作,我应该阻止webview to open new BrowserWindow并自己创建。

以下代码失败:

// in renderer process
webview.addEventListener('new-window', function(event) {
    event.preventDefault();
    // I also tried 'event.defaultPrevented = true;'
    // or 'return false;'
});

触发了侦听器,但我无法阻止新窗口的打开。

有人写道,只能在主进程中阻止新窗口。

所以我在main.js中添加以下代码:

// in main process
var electron      = require('electron');
var BrowserWindow = electron.BrowserWindow;

mainWindow = new BrowserWindow({
    "width": 970,
    "height": 500,
    "center": true,
    'title': 'Main window',
    "autoHideMenuBar": true
});

mainWindow.loadURL('file://' + root + '/index.html');

mainWindow.webContents.on('new-window', function(event) {
    console.log(event);
});

此时event 'new-window'根本未触发。我认为这是因为只有当渲染器处理请求以window.open打开一个新窗口时,该事件才有效。但在我的情况下,新窗口由&lt; webview&gt;打开。标记,而不是渲染器过程。所以我没有阻止打开新窗口,因为这是两个独立的过程。

所以我决定在它打开后获得新窗口。

// in renderer process
var electron = require("electron");
var remote   = electron.remote;

webview.addEventListener('new-window', function(event) {
    var win      = remote.BrowserWindow.getFocusedWindow();
    var contents = win.webContents;

    win.setIcon(root+"/img/favicon.ico");
    win.setMenuBarVisibility(false);

    contents.on('dom-ready', function() {
        contents.openDevTools();
    })
});

之后我真的不知道下一步该做什么...如何附加window.opener并解决我的问题

我在github上发现了很多类似的问题。但是所有这些都合并到一个问题#1865,到目前为止还没有明确的答案。

我知道解决方案存在。勇敢的开发者解决了这个问Brave browser也使用电子工作正常,与普通浏览器相同。但在查看sources时,我找不到答案。

他们甚至做了测试来检查window.opener是否正常工作。但我没能从git存储库安装Brave。在“npm-start”之后,它显示“错误:%1无效的Win32应用程序”。我有Windows 10.(另一个原因让我转向Linux。希望很快就能实现。)

所以,我的问题是:如何将回调数据从新窗口发送回创建此窗口的webview。提前谢谢。

1 个答案:

答案 0 :(得分:0)

首先,要自己处理新窗口弹出窗口,您必须禁用allowpopups(即从webview中删除allowpopups属性) 这样,新窗口事件将被触发,但在您明确编码之前不会打开任何弹出窗口。

对于某些社交或sso登录所需的window.opener功能,电子没有足够的支持。见issue 1865

勇敢的团队在他们的电子分支中以有限的方式实施了它。见issue 4175。 您可以尝试:

  • 使用Brave的fork of electron(不确定它是否符合您的需求,因为他们已经做了一些重大更改)
  • 制作一个PR电子,以整合来自fork的window.opener的支持。
  • 通过注入实现缺少window.opener方法的脚本,为您需要的方法创建自己的polyfill。您可以使用window.opener.send与渲染器进程进行通信)