Electron.js:如何为窗口创建单独的下载webContents.session?
我有一个 Electron文件管理器应用程序,它为不同的目的创建了 2 个窗口:
-
quickView用于预览本地文件的渲染器窗口。它使用“will-download”侦听器通过阻止下载来检测不受支持的文件。 -
main主渲染器窗口。它使用“will-download”侦听器来下载文件。
每个都有自己的will-download听众附加到他们的会话。但是由于某种原因,quickView侦听器覆盖了main侦听器。
窗口 1
在下一行中,我正在will-download为“主”进程创建一个侦听器。这个监听器的目的是下载文件:
https://github.com/aleksey-hoffman/sigma-file-manager/blob/55fd2462cf83898610883191807b7488fb5bdf89/src/utils/downloadManager.js#L133
win.webContents.session.on('will-download', listener)
windows.main下面一行中的参数是win上面一行中的引用:
https://github.com/aleksey-hoffman/sigma-file-manager/blob/55fd2462cf83898610883191807b7488fb5bdf89/src/electronMain.js#L516
const resultInfo = await downloadManager.download(windows.main, {
const resultInfo = await downloadManager.download(windows.main, {
窗口 2
在下一行中,我正在will-download为“quickView”窗口创建一个侦听器。此侦听器的目的是检测不受支持的文件(在 Chromium 中触发下载事件)并阻止下载事件:
https://github.com/aleksey-hoffman/sigma-file-manager/blob/55fd2462cf83898610883191807b7488fb5bdf89/src/electronMain.js#L232
windows.quickViewWindow.webContents.session.once('will-download', _willDownloadHandler)
我还没有找到另一种检测不受支持的文件的方法,这就是我will-download首先使用事件的原因。
问题
出于某种原因,will-download在处理程序的quickView窗口覆盖的处理程序main:
当我在此处触发应用更新下载事件时(来自main流程):
https://github.com/aleksey-hoffman/sigma-file-manager/blob/55fd2462cf83898610883191807b7488fb5bdf89/src/electronMain.js#L516
它触发quickView渲染器窗口的事件处理程序:
https://github.com/aleksey-hoffman/sigma-file-manager/blob/55fd2462cf83898610883191807b7488fb5bdf89/src/electronMain.js#L241
function _willDownloadHandler (event, item, webContents) {
...
windows.main.webContents.send('load:webview::failed', {path: fileURL})
部分修复
我通过为窗口会话指定自定义分区名称来部分解决此提交中的问题quickView,因此它不使用默认会话并且不覆盖will-download由main以下人员创建的侦听器:
主要流程:
windows.quickViewWindow = new electron.BrowserWindow({
...
webPreferences: {
partition: 'quickPreview',
...
windows.quickViewWindow.webContents.session.once(
'will-download',
(event, item, webContents) => {
event.preventDefault()
...
}
)
快速查看窗口.html:
ipcRenderer.on('load:webview', (event, data) => {
...
webviewNode.setAttribute('partition', 'quickPreview')
但是这个修复导致了另一个问题:
-
快速查看窗口在生产版本中停止工作(可能与协议不适用于非默认会话分区有关)
-
将自定义分区设置为 webview 会导致在创建包含此 webview 的窗口时在生产中弹出 Windows 协议链接关联:
我认为这可能是app://由electron-builder-plugin创建的自定义协议引起的。似乎弹出窗口是由“应用程序”链接触发的。
或者,这可能是因为我在此行附近的某处创建窗口时错误地设置了协议:
https://github.com/aleksey-hoffman/sigma-file-manager/blob/47ce65bdac78e5c9b17315f16623d40d81dcf1bb/src/electronMain.js#L203
重现:
- 下载项目
git clone https://github.com/aleksey-hoffman/sigma-file-manager.git
cd sigma-file-manager
npm install
git checkout 47ce65b
npm run electron:build
git clone https://github.com/aleksey-hoffman/sigma-file-manager.git
cd sigma-file-manager
npm install
git checkout 47ce65b
npm run electron:build
- 安装构建的应用程序
./dist_electron - 在应用程序启动期间,您可以看到弹出窗口
- 在导航器页面上选择任何支持的文件(图像/文本/等)
- 新闻空间(快速查看窗口应该打开)
git checkout 5246252
npm run electron:build
git checkout 5246252
npm run electron:build
l>
笔记:
我刚刚回滚了 47ce65b 提交并添加了一些测试值,以便更容易调试
要切换到最新提交并创建生产版本:
console.log()里面的所有内容electronMain.js都显示在终端(命令行)窗口(不是开发者工具控制台)中。
触发快速查看功能:
要触发下载事件,您只需打开“导航器”页面并从 Internet 拖放任何文件(或网站 URL)即可。它将触发错误的 will-download 事件处理程序(quickView 窗口的处理程序),您应该会看到控制台消息。
包含此 webview 的 quickView 窗口是在app.ready事件上创建的。当指定了 partition 时,会在创建 quickView 窗口后立即出现弹出窗口:
https://github.com/aleksey-hoffman/sigma-file-manager/blob/47ce65bdac78e5c9b17315f16623d40d81dcf1bb/src/electronMain.js#L698
更新:
较小的复制示例:
我能够使用以下代码重现它:
当setTimeout运行时,我看到以下console.log()信息:
trigger window 1 download
window will-download handler 1
window will-download handler 2
从日志中可以看出,will-download 事件触发了两个窗口的事件处理程序
如果我为每个窗口指定一个单独的分区,共享事件处理程序的问题就会得到解决,但我会遇到上面提到的第二个问题 - 启动时会弹出链接关联