Maison > Questions et réponses > le corps du texte
P粉6158297422023-08-28 19:14:20
Tout ce qui figure dans la documentation officielle ne peut pas être implémenté directement n'importe où dans le code. Vous devez avoir une compréhension concise de l’environnement et des processus.
Environnement/Processus | Description |
---|---|
Principal | L'API est plus proche du système d'exploitation (niveau bas). Ceux-ci incluent le système de fichiers, les fenêtres contextuelles de notification basées sur le système d'exploitation, la barre des tâches, etc. Ceux-ci sont implémentés via une combinaison de l'API principale d'Electron et de Node.js |
Préchargé | Récente Annexe pour éviter les fuites de la puissante API disponible dans l'environnement principal. Pour plus de détails, consultez le Journal des modifications d'Electron v12< /a> et le Issue #23506. |
Rendu | API pour les navigateurs Web modernes tels que DOM et JavaScript frontal (avancé). Ceci est réalisé grâce à Chromium. |
Scène | contextIsolation |
nodeIntegration |
Remarques |
---|---|---|---|
A | 假 |
假 |
Aucun préchargement requis. Node.js est disponible dans Main mais pas dans Renderer. |
B | 假 |
true |
Aucun préchargement requis. Node.js est disponible dans Main et Renderer. |
C | true |
假 |
Nécessite un préchargement. Node.js est disponible en chargement principal et en préchargement, mais pas en rendu. Par défaut. Recommandé. |
D | true |
true |
Nécessite un préchargement. Node.js est disponible dans Main, Preload et Renderer. |
Vous devez utiliser la communication inter-processus (IPC) d'Electron pour que le processus principal et le processus de rendu communiquent.
BrowserWindow.webContents.send() code>
Méthode pour envoyer des messages au moteur de renduipcMain.handle()
ipcMain.handle() Méthode pour recevoir les messages du moteur de renduPrincipal
/** * Sending messages to Renderer * `window` is an object which is an instance of `BrowserWindow` * `data` can be a boolean, number, string, object, or array */ window.webContents.send( 'custom-endpoint', data ); /** * Receiving messages from Renderer */ ipcMain.handle( 'custom-endpoint', async ( event, data ) => { console.log( data ) } )
Préchargé
const { contextBridge, ipcRenderer } = require('electron') contextBridge.exposeInMainWorld( 'api', { send: ( channel, data ) => ipcRenderer.invoke( channel, data ), handle: ( channel, callable, event, data ) => ipcRenderer.on( channel, callable( event, data ) ) } )
Renderer
/** * Sending messages to Main * `data` can be a boolean, number, string, object, or array */ api.send( 'custom-endpoint', data ) /** * Receiving messages from Main */ api.handle( 'custom-endpoint', ( event, data ) => function( event, data ) { console.log( data ) }, event);
Gardez votre engagement envers le même processus/environnement autant que possible. Vos promesses sur main devraient rester sur main. Votre engagement envers le renderer doit également rester sur le moteur de rendu. Ne vous engagez pas à passer du programme principal au préchargeur puis au moteur de rendu.
La plupart de votre logique métier doit toujours être du côté principal ou du moteur de rendu, mais elle ne doit jamais être en préchargement. En effet, le préchargement existe presque exclusivement en tant que support. La précharge doit être très faible.
Dans le cas d'OP , fs
fs doit être implémenté côté maître.
P粉3233748782023-08-28 11:18:17
J'ai publié un article plus volumineux sur l'histoire d'Electron
(Comment la sécurité a changé dans les versions d'Electron) et d'autres considérations de sécurité que les développeurs d'Electron peuvent prendre pour garantir une utilisation correcte du préchargement dans les nouveaux documents d'applications.Comme un autre utilisateur l'a demandé, permettez-moi d'expliquer ma réponse ci-dessous.
preload.js
的正确方法是在您的应用可能需要 require
Exposez un wrapper de liste blanche autour de n'importe quel module utilisant
require
或通过 preload.js
中的 require
Du point de vue de la sécurité, exposer < a href="https://github.com/electron/ Electron/issues/9920#issuecomment-575839738" rel="noreferrer"> tout ce qui est récupéré par un appel est dangereux (voir mon commentaire
Pour faire cela correctement, vous devez définir la < 上启用许多选项code>BrowserWindowrequire
comme je le détaille ci-dessous. La définition de ces options force votre application Electron à communiquer via IPC (Inter-Process Communication) et isole les deux environnements l'un de l'autre. Configurer votre application de cette manière vous permet de valider tout ce qui dans le backend pourrait être un module require
main.js
const { app, BrowserWindow, ipcMain } = require("electron"); const path = require("path"); const fs = require("fs"); // Keep a global reference of the window object, if you don't, the window will // be closed automatically when the JavaScript object is garbage collected. let win; async function createWindow() { // Create the browser window. win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: false, // is default value after Electron v5 contextIsolation: true, // protect against prototype pollution enableRemoteModule: false, // turn off remote preload: path.join(__dirname, "preload.js") // use a preload script } }); // Load app win.loadFile(path.join(__dirname, "dist/index.html")); // rest of code.. } app.on("ready", createWindow); ipcMain.on("toMain", (event, args) => { fs.readFile("path/to/file", (error, data) => { // Do something with file contents // Send result back to renderer process win.webContents.send("fromMain", responseObj); }); });preload.js
const { contextBridge, ipcRenderer } = require("electron"); // Expose protected methods that allow the renderer process to use // the ipcRenderer without exposing the entire object contextBridge.exposeInMainWorld( "api", { send: (channel, data) => { // whitelist channels let validChannels = ["toMain"]; if (validChannels.includes(channel)) { ipcRenderer.send(channel, data); } }, receive: (channel, func) => { let validChannels = ["fromMain"]; if (validChannels.includes(channel)) { // Deliberately strip event as it includes `sender` ipcRenderer.on(channel, (event, ...args) => func(...args)); } } } );index.html🎜
<!doctype html> <html lang="en-US"> <head> <meta charset="utf-8"/> <title>Title</title> </head> <body> <script> window.api.receive("fromMain", (data) => { console.log(`Received ${data} from main process`); }); window.api.send("toMain", "some data"); </script> </body> </html>