#1 控制<webview>中彈出的窗口
需要監聽一個<webview>的彈窗事件時,有兩種方法:
document.getElementById('webview1').addEventListener('new-window', (e) => {
console.log(e.url)
}
和
document.getElementById('webview1').addEventListener('dom-ready', () => {
const contents = document.getElementById('webview1').getWebContents();
contents.on('new-window', (event, url) => {
event.preventDafault();
console.log(url);
});
});
第一種更簡單。
第二種看起來支持阻止事件傳播,但實際上,如果啟用<webview>的allowpopups,窗口仍會彈出。
一種好的做法是,禁用allowpopups,使用第一種方法來監聽,并發送想要的url給主進程,由主進程創建和管理window。
#2 使用require.js的頁面加載報錯
有些頁面使用了require.js加載模組,它增加了require()方法,這和node自身require的關鍵字沖突,可能帶來錯誤或其他無法預測的問題。
在這種頁面中,應該設置:
new BroswerWindow({
webPreferences: {
nodeIntegration: false,
}
});
特別的是,如果是webview中彈出的窗口,并不存在這個問題,因為其默認關閉了這個選項。
#3 session.webRequest中使用file://協議
如果使用session.webRequest.onBeforeRequest(listener)
來攔截并替換頁面中的請求,需要提供一個redirectURL。
在window的url為遠程url時,不存在任何問題。但當url為file://...時,會報錯:Not allowed to load local resource
。這是瀏覽器的安全限制。
所幸Electron提供了API以修改這種限制。
設置window的屬性如下:
webPreferences: {
webSecurity: false
}
這時file://...指向的本地文件可以正常加載。
另外,webPreferences.allowRunningInsecureContent
也是同類型的設置項,決定是否允許https頁面中加載http資源。
這些安全屬性是Electron不建議修改的,如果是在開發商業產品則不建議修改。
可以通過啟動一個靜態資源服務器來通過http協議暴露本地文件。
#4 <webview>設定attr.src時不能指向新頁面
某些條件下會遇到這個問題。換為iframe則正常刷新。
測試的一種解決方法是,隔一定時間后,再設置src。至少10ms。
------ 2018-3-28更新 ------
經測試發現,當<webview>的樣式(或其上級元素的樣式)為display:none
時,為其設定src會無效。
有時我們希望<webview>平時隱藏,等到src設定好后再加載。
具體實施時,可以不使用display:none
隱藏元素,而是使用width:0;height:0
等方式。
------ 2018-3-29更新 ------
如果更改webview的src,可能會因src加載需要時間,而產生src變更,webview內顯示仍為原來頁面的情況。
可以為webview注冊commit-load和dom-ready監聽器,在其開始加載時隱藏,在其加載好DOM時顯示。注意隱藏不要用display:none
。
#5 持續打包
如果需要打包應用程序,最好從開發之始就經常build并驗證程序是否正確執行。
否則最后打包時發現程序不能運行,再找問題就很難了。
推薦使用electron-forge來生成項目。對已經寫好的項目,也可以逐步移植到electron-forge生成的初始項目里。
一般我們還需要設置忽略的文件、圖標等,這些設置可能在electron-forge的文檔中找不到。其實這個庫本身是多個庫的集合,很多設置需要去其依賴的庫的文檔里找。
下面列出一些重要配置項:
// package.json
{
"productName": "掃雷", // 應用名
"version": "1.0.0", // 版本
"description": "游信審核器Electron版", // 鼠標移到應用圖標上時顯示的描述
"config": {
"forge": {
"electronPackagerConfig": {
"icon": "./static/icon.ico", // 應用圖標
"ignore": "(.idea)|(lite.db)" // 打包時忽略的文件(夾)
}
}
}
}