【问题标题】:Electron: webview doesn't receive callback code from new created window电子:webview 没有从新创建的窗口接收回调代码
【发布时间】:2016-11-30 03:24:44
【问题描述】:

我有一个桌面应用程序,可以用作简单的浏览器。它有带有显示网页的网页视图的标签。

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

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

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

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

在寻找解决方案的不同来源时,我发现这个问题也与 window.opener 有关,这在电子的最早版本中并不完全支持。但是根据 github 上的issue#1865,如果我通过 window.open 方法打开窗口,现在可以使用完整的 window.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 打开一个新窗口时才起作用。但在我的情况下,新窗口是由 标签打开的,而不是由渲染器进程打开的。所以我没能阻止新窗口打开,因为这是两个独立的进程。

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

// 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 上发现了很多类似的问题。但是都合并到一个issue#1865,目前还没有明确的答案。

我知道解决方案存在。勇敢的开发人员解决了这个问题。 Brave browser 也使用电子制作,与一般浏览器一样正常工作。但是我在浏览它的sources时找不到答案。

他们甚至进行了测试以检查 window.opener 是否正常工作。但我未能从 git 存储库安装 Brave。在“npm-start”之后它显示“错误:%1 不是有效的 Win32 应用程序”。我有 Windows 10。(只是另一个原因让我切换到 Linux。希望尽快实现。)

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

【问题讨论】:

    标签: javascript webview chromium electron new-window


    【解决方案1】:

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

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

    Brave 团队在他们的 Electron 分支中以受限的方式实现了它。见issue 4175。 您可以尝试:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-05
      • 1970-01-01
      • 2014-05-27
      • 1970-01-01
      • 2012-11-11
      • 2020-06-15
      • 1970-01-01
      相关资源
      最近更新 更多