某個同事說,現有的Electron
內建瀏覽器在F12
的效能測試裡,發現JS檔案無法定位,或者定位錯誤,問我怎麼辦。
看了下,在MacOS
中是沒問題的,只有Windows
下莫名其妙有。但我就這點兒能耐,又能怎麼辦?
只能升級Electron
試試唄。於是,將electron
的依賴包從v31
升級到最新穩定版本v32
。
開始以為挺順利,沒想到看到專案的網路裡報錯了:
控制檯也是提示本地資原始檔載入失敗:
這就有點兒讓人懵逼了。
我下意識以為是瀏覽器改變了什麼安全策略,但追蹤後發現瀏覽器中直接載入的file:///
是沒問題的,只是WebAssembly(wasm)
載入的有毛病。
為什麼有的資源會用
wasm
載入呢?原因是這些資源進行了加密,用wasm
進行解密,可以有效增加外界破解難度。
再看了下,Electron v31
用的126
的Chromium
核心,v32
用的是128
的核心(在這裏看Chromium
核心版本)。
但其實在瀏覽器裡是無法直接載入本地檔案的,這個功能只有Electron
或Tauri
這種App
才能做到,所以一時無法確定是瀏覽器的鍋,還是Electron
的鍋。
走投無路之際,我問了下GPT
:
GPT
說的這句看著是有道理的:
在新版本的 Electron 中,可能對
file://
或其他自定義URL scheme
的支援做了一些修改。例如,WebAssembly
載入本地檔案可能涉及到資源路徑的解析,而 Electron 132 版本可能對非標準的 URL scheme 進行了更嚴格的驗證,導致無法正確識別file://
。
下面第三條其實我開始Google
搜尋見到過,確實可以攔截到file:///
的檔案請求:
但給的示例是用的interceptFileProtocol
,導致所有file
請求都報錯了:
protocol.interceptFileProtocol('file', (req, callback) => { const url = req.url.substr(8) callback(decodeURI(url)) })
現在修改成registerFileProtocol
,試上一下:
protocol.registerFileProtocol('file', (request, callback) => { const filePath = request.url.replace(/^file:\/\//, '') callback({ path: filePath }) })
居然好了!
由於這個API已經被提示不推薦使用:
所以又找了下替代方案,這樣看起來優雅多了:
protocol.handle('file', (req) => { return net.fetch(req.url, { bypassCustomProtocolHandlers: true }) })
問題解決了,但回到我們開始的問題,到底是Chromium
的鍋,還是Electron
的鍋呢?
我還是不確定。去掉這段程式碼,嘗試將Electron
降到v32
的第一個版本32.0.0
,仍然是報錯;降到v31
的最後一個版本31.6.0
,是沒問題的。
看Electron v32
的發版日誌裡,破壞性變更僅有移除上傳檔案File
的不標準的path
:
而看Chromium
v127 的發版日誌 和 v128 的發版日誌也沒看出個所以然來,有安全層面的更新,不清楚是否有關。希望有大佬解答下。
搞客戶端開發有時候不得不升級依賴,但一升級又可能有這樣那樣的問題,無奈。