[笔记]electron 踩到的坑

file 协议缺失 content-type

通过 electron.protocol.registerFileProtocolelectron.protocol.interceptFileProtocol 产生的协议, Response Header 中是不包含 content-type 的. 这会导致在某些奇怪的问题, 比如注册的 serviceworker 无法被识别等.

解决方法是使用 registerBufferProtocol 代替 registerFileProtocol 协议.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
interceptBufferProtocol('file', (request, callback) => {
const filePath = getFilePathFromRequest(request)
fs.readFile(filePath, (err, data) => {
if (err) {
// report error
callback()
} else {
callback({
// 通过开源库 mime-types 获得后缀对应的 mime type
mimeType: getMimeType(filePath),
data
})
}
})
})

上面的例子可以看出来 buffer protocol 完美的替代了 file protocol

clearStorageData 清理 localStorage 失败

通过 session.defaultSession.clearStorageData 清理 file:// 下的 localStorage 会失败, 必须强制指定一个 origin

1
2
3
4
session.defaultSession.clearStorageData({
origin: process.env.APP_PROTOCOL,
storages: ['localstorage']
}, callbackFn)

给 electron 提了一个 issue, 有开发者答复说是 chromium 的 bug, 会在升级到 chromium66的内核后修复. 所以理论上 electron 3+ 的版本不再会有这个问题, 待验证

Electron 对 io 操作有一定的优化, setCookie 并不是立即作用于磁盘上.

推荐在 before-quit 的时候调用一次 cookies.flushStore

代理导致 electron 应用崩溃

我所遇到过 Electron 的问题中最费解的一个, 至今不理解这个问题原理是什么. 只知道当系统中设置了 pac 方式的代理时, 网络状态的切换会导致程序崩溃.

我的解决方案是, 在 electron 中通过 session.setProxy 的方式强制设置一个代理(比如设置所有请求走 DIRECT). 就可以防止程序崩溃.

文件关联

electron-builder 提供了 fileAssociations 配置项可以在安装时注册文件的启动方式.

在 mac 系统中, 我们可以通过 electron.app.on(‘open-file’) 事件监听打开文件的行为.

由于打开文件的行为可以触发客户端的启动, open-file 事件的注册必须尽可能的早(在 app.ready 之前), 并在 app.ready 后触发对应的操作.

windows 与 linux 下, 可以在 process.env.argv 中获得打开的文件

在 electron 中使用 Chrome 扩展

官方文档里有一篇指南: https://electronjs.org/docs/tutorial/devtools-extension 但比较不易被人发现.

react-dev-tool 举例

1
BrowserWindow.addDevToolsExtension('/Users/whoami/Library/Application Support/Google/Chrome/Default/Extensions/fmkadmapgofadopljbjfkapdkoienihi/3.3.1_0/')

扩展的版本名会随着 Chrome 扩展升级变化.

Electron 2 -> 3 的坑

抛开官方弃用的 Api 外, 还有不少由于 chromium 升级造成的问题:

1. webview-tag 的 html 事件不再对外冒泡

解决方法是通过 ipc 手动触发一个外部的对应事件

https://github.com/electron/electron/issues/14258#issuecomment-416794070

2. webview-tag 中通过菜单项的复制粘贴很多场合不正常

主要是 windows 的场合, 部分菜单功能在 windows, macos 下均不可用 (比如 copyWithStyle)

解决方法是不要用菜单的 role 属性, 而是通过菜单项手动触发 webcontent 的对应指令

https://github.com/electron/electron/issues/15219

3. clearStorageData 在 file:// 下无法删除 indexdb

甚至在 chrome-dev-tool 下清除也是无效的.

目前尚未找到完美的替代方法, 只能通过渲染进程中 indexedDB.deleteDatabase 逐个删除.