在 Electron 中正確利用 preload.js:綜合指南
P粉197639753
2023-08-27 20:25:30
<p>我嘗試在我的 <code>renderer</code> 進程中使用節點模組(在本例中為 <code>fs</code>),如下所示:</p>
<pre class="brush:php;toolbar:false;">// main_window.js
const fs = require('fs')
function action() {
console.log(fs)
}</pre>
<p><sup>注意:當我按 <code>main_window</code> 中的按鈕時,會呼叫 <code>action</code> 函數。 </sup></p>
<p>但這會產生錯誤:</p>
<pre class="brush:php;toolbar:false;">Uncaught ReferenceError: require is not defined
at main_window.js:1</pre>
<p>我可以解決這個問題,正如這個接受的答案所建議的,通過在初始化<code>main_window</code> 時將這些行添加到我的<code>main.js</code>中:</p>
<pre class="brush:php;toolbar:false;">// main.js
main_window = new BrowserWindow({
width: 650,
height: 550,
webPreferences: {
nodeIntegration: true
}
})</pre>
但是,根據文檔,這不是最好的做法,我應該創建一個<code>preload.js</code> 文件並在其中加載這些Node 模組,然後在我的所有<code>renderer</code>中使用它流程。像這樣:<p><br /></p>
<p><code>main.js</code>:</p>
<pre class="brush:php;toolbar:false;">main_window = new BrowserWindow({
width: 650,
height: 550,
webPreferences: {
preload: path.join(app.getAppPath(), 'preload.js')
}
})</pre>
<p><code>preload.js</code>:</p>
<pre class="brush:php;toolbar:false;">const fs = require('fs')
window.test = function() {
console.log(fs)
}</pre>
<p><code>main_window.js</code>:</p>
<pre class="brush:php;toolbar:false;">function action() {
window.test()
}</pre>
<p>而且它有效! </p>
<hr />
<p>現在我的問題是,我應該在<code>preload.js</code> 中寫<code>renderer</code> 進程的大部分程式碼,這不是違反直覺的嗎(因為只有在<code>preload.js</code> 我才能訪問Node 模組)然後只呼叫每個<code>renderer.js</code> 檔案中的函數(例如此處,<code>main_window. js</code>)?我在這裡不明白什麼? </p>
考慮這個例子
並非官方文件中的所有內容都可以在程式碼中的任何位置直接實現。您必須需要對環境和流程有簡潔的了解。
上下文隔離和節點整合
contextIsolation
#nodeIntegration
假
假
假
true
true
假
true
true
如何正確使用預載?
您必須使用 Electron 的進程間通訊 (IPC) 才能使主進程和渲染進程進行通訊。
BrowserWindow.webContents.send() code>
傳送訊息給渲染器的方法ipcMain.handle()
從渲染器接收訊息的方法實作範例
主要
預先載入
渲染器
#使用 Promise 怎麼樣?
盡可能遵守對相同流程/環境的承諾。您在 main 上的承諾應該保留在 main 上。您對渲染器的承諾也應該保留在渲染器上。不要做出從主程式跳到預先載入程式再到渲染器的承諾。
檔案系統
您的大部分業務邏輯仍應位於主端或渲染器端,但絕不應位於預先載入中。這是因為預載幾乎只是作為一種媒介而存在。預載應該非常小。
在OP的情況下,
fs
應該在主端實作。編輯 2022 年
我已經發表了一篇關於Electron 歷史的較大文章( Electron 版本中的安全性如何發生變化)以及Electron 開發人員可以採取的其他安全注意事項,以確保在新應用程式中正確使用預先載入檔案。
編輯 2020
正如另一位用戶所問,讓我在下面解釋我的答案。
在 Electron 中使用
preload.js
的正確方法是在您的應用程式可能需要require
的任何模組周圍公開白名單包裝器。從安全性角度來看,公開
require
或透過preload.js
中的require
呼叫檢索的任何內容都是危險的(請參閱我的評論以獲取更多解釋原因)。如果您的應用程式載入遠端內容(許多應用程式都會這樣做),則尤其如此。為了正確執行操作,您需要在 BrowserWindow 正如我在下面詳細介紹的。設定這些選項會強制您的電子應用程式透過 IPC(進程間通訊)進行通信,並將兩個環境相互隔離。像這樣設定您的應用程式可以讓您驗證後端中可能是
require
模組的任何內容,而客戶端不會對其進行篡改。下面,您將找到一個簡短的範例,介紹我所討論的內容以及它在您的應用程式中的外觀。如果您是新手,我可能建議使用
secure-electron-template
(我是其作者)在構建電子應用程式時從一開始就融入了所有這些安全最佳實踐。此頁面也有很好的資訊使用 preload.js 製作安全應用程式時所需的架構。
main.js
preload.js
#index.html
#