electron 打开 about:blank#blocked 的新窗口
发布于
更新于
拦截新窗口时遇到了一个无效的url
正文
我们现在的项目产品简单说可以算是electron打造的一个浏览器,为了实现浏览器的核心功能,我们拦截了页面中打开新窗口的事件,并由我们客户端内部逻辑去处理。
今天遇到一个oncall,某些网页上,在页面内打开新窗口时,会被electron的事件监听器读取到一个奇怪的值,
我尝试打个日志看一下,主要代码如下:
view.webContents.setWindowOpenHandler((details) => {
console.log(details);
// ... 这里有些业务逻辑省略 ...
return { action: 'deny' };
});
输出:
{
url: 'about:blank#blocked',
frameName: '',
features: '',
disposition: 'foreground-tab',
referrer: { url: '', policy: 'strict-origin-when-cross-origin' },
postBody: undefined
}
这个details看起来很奇怪,因为它的url是个无效的值,而正常情况下这个值应该是需要被打开新窗口的url地址。但是诡异的事情就在这里,尽管我在这个事件中无法读取到url,但是如果我不去拦截、让electron原本默认的逻辑去处理,是可以打开一个新窗口并导航到正确的url上去的;更别说,同一个网站的同一个行为在常规浏览器(chrome等)中表现更是正常。
我依然不能解释其中的原因,大概猜测,问题可能是electron在处理chromium的事件的时候丢失了一些附带信息,没有暴露到js层来,以至于开发者无法针对这类特殊的事件进行处理。
解决方案参考这里。
最后我决定先让这个新窗口在后台隐藏打开,
view.webContents.setWindowOpenHandler((details) => {
if (details.url === 'about:blank#blocked') {
// ... 隐藏模式打开新窗口(用BrowserView即可)...
return { action: 'allow', outlivesOpener: false, overrideBrowserWindowOptions: { show: true } };
}
return { action: 'deny' };
});
然后从这个窗口中取得真实url之后,再执行原本的逻辑:
// 对隐藏窗口的事件进行监听,获取真实url
view.webContents.on('did-create-window', (window, details) => {
if (details.url === 'about:blank#blocked') {
window.webContents.on('will-navigate', (evt, url) => {
// ... 这里拿到了真实的url,可以去做事情了(例如在前台标签页打开显示)...
window.destroy();
});
}
});
实际体验速度还可以,正常网速情况下不会出现明显的延迟情况。