Preload.js in Electron richtig nutzen: Eine umfassende Anleitung
P粉197639753
2023-08-27 20:25:30
<p>Ich habe versucht, ein Knotenmodul (in diesem Fall <code>fs</code>) in meinem <code>renderer</code>-Prozess zu verwenden: </p>
<pre class="brush:php;toolbar:false;">// main_window.js
const fs = require('fs')
Funktion action() {
console.log(fs)
}</pre>
<p><sup>Hinweis: Wenn ich die Schaltfläche in <code>main_window</code> drücke, wird die Funktion <code>action</code> aufgerufen. </sup></p>
<p>Aber dies erzeugt den Fehler: </p>
<pre class="brush:php;toolbar:false;">Uncaught ReferenceError: require ist nicht definiert
unter main_window.js:1</pre>
<p>Ich konnte dieses Problem lösen, indem ich beim Initialisieren von <code>main_window</code> diese Zeilen zu meiner <code>main.js</code> hinzufügte. /p>
<pre class="brush:php;toolbar:false;">// main.js
main_window = neues BrowserWindow({
Breite: 650,
Höhe: 550,
webPreferences: {
nodeIntegration: wahr
}
})</pre>
Laut Dokumentation ist dies jedoch nicht die beste Vorgehensweise. Ich sollte eine Datei <code>preload.js</code> erstellen und diese Node-Module darin und dann in alle meine <code>renderer</ laden. Code> Verwenden Sie ihn dabei.So:<p><br /></p>
<p><code>main.js</code>:</p>
<pre class="brush:php;toolbar:false;">main_window = new BrowserWindow({
Breite: 650,
Höhe: 550,
webPreferences: {
Vorladen: 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>Und es funktioniert! </p>
<hr />
<p>Meine Frage ist nun, ob es nicht kontraintuitiv ist, dass ich den größten Teil des Codes für den <code>renderer</code>-Prozess in <code>preload.js</code> schreiben sollte Sie haben nur Zugriff auf das Node-Modul in <code>preload.js</code>) und rufen dann einfach die Funktionen in jeder <code>renderer.js</code>-Datei auf (wie hier, <code>main_window). js</code>)? Was verstehe ich hier nicht? </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