contextBridge
History
| Version(s) | Changes |
|---|---|
None |
|
Erstellen Sie eine sichere, bidirektionale, synchrone Brücke über isolierte Kontexte.
Process: Renderer
Im Folgenden finden Sie ein Beispiel für das Verfügbarmachen einer API für einen Renderer aus einem isolierten Preload-Skript:
// Preload (Isolierter Kontex)
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld(
'electron',
{
doThing: () => ipcRenderer.send('do-a-thing')
}
)
// Renderer (Hauptkontext)
window.electron.doThing()
Glossar
Hauptkontext
Der "Hauptkontext" ist der JavaScript-Kontext, in dem Ihr Hauptrenderercode ausgeführt wird. Standardmäßig führt die Seite, die Sie in Ihren Renderer laden, Code in diesem Kontext aus.
Isolierter Kontext
Wenn contextIsolation in Ihrem webPreferences aktiviert ist (dies ist das Standardverhalten seit Electron 12.0.0), werden Ihre preload-Skripte in einer "Isolierte Welt" ausgeführt. You can read more about context isolation and what it affects in the security docs.
Methoden
Das contextBridge Modul hat folgende Methoden:
contextBridge.exposeInMainWorld(apiKey, api)
apiKeystring - Das Schlüsselwort, mit dem die API inwindoweingefügt werden soll. Die API wird aufwindow[apiKey]zugänglich sein.apiany - Ihre API, weitere Informationen darüber, was diese API sein kann und wie sie funktioniert, finden Sie unten.
contextBridge.exposeInIsolatedWorld(worldId, apiKey, api)
worldIdInteger - The ID of the world to inject the API into.0is the default world,999is the world used by Electron'scontextIsolationfeature. Using 999 would expose the object for preload context. We recommend using 1000+ while creating isolated world.apiKeystring - Das Schlüsselwort, mit dem die API inwindoweingefügt werden soll. Die API wird aufwindow[apiKey]zugänglich sein.apiany - Ihre API, weitere Informationen darüber, was diese API sein kann und wie sie funktioniert, finden Sie unten.
contextBridge.executeInMainWorld(executionScript) Experimentell
executionScriptObjektfunc(...args: any[]) => any - A JavaScript function to execute. This function will be serialized which means that any bound parameters and execution context will be lost.argsany[] (optional) - An array of arguments to pass to the provided function. These arguments will be copied between worlds in accordance with the table of supported types.
Returns any - A copy of the resulting value from executing the function in the main world. Refer to the table on how values are copied between worlds.
Beispiel
API
Die API, die Sie exposeInMainWorld bereitstellten muss eine Function, string, number, Array, boolean oder ein Objekt sein, dessen keys Strings und Werte eine Function, string, number, Array, boolean sind oder ein anderes verschachteltes Objekt, das dieselben Bedingungen erfüllt.
Function-Werte werden in den Renderkontext proxidiert, und alle anderen Werte werden kopiert und eingefroren. Alle Daten / Primitive, die der API gesendet werden, werden unveränderlich und Aktualisierungen auf beiden Seiten der Bridge führen nicht zu einem Update auf der anderen Seite.
Im Folgenden finden Sie ein Beispiel für eine komplexe API:
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld(
'electron',
{
doThing: () => ipcRenderer.send('do-a-thing'),
myPromises: [Promise.resolve(), Promise.reject(new Error('whoops'))],
anAsyncFunction: async () => 123,
data: {
myFlags: ['a', 'b', 'c'],
bootTime: 1234
},
nestedAPI: {
evenDeeper: {
youCanDoThisAsMuchAsYouWant: {
fn: () => ({
returnData: 123
})
}
}
}
}
)
An example of exposeInIsolatedWorld is shown below:
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInIsolatedWorld(
1004,
'electron',
{
doThing: () => ipcRenderer.send('do-a-thing')
}
)
// Renderer (In isolated world id1004)
window.electron.doThing()
API-Funktionen
Function Werte, die Sie durch die contextBridge binden, werden durch Electron proxiiert, um sicherzustellen, dass Kontexte isoliert bleiben. Dies führt zu einigen wichtigen Einschränkungen, die wir unten beschrieben haben.
Parameter / Error / Return Type support
Da Parameter, Fehler und Rückgabewerte kopiert werden, wenn sie über die Bridge gesendet werden, gibt es nur bestimmte Typen, die verwendet werden können. Einfach gesagt, wenn der Typ, den Sie verwenden möchten, serialisiert und in dasselbe Objekt deserialisiert werden kann, funktioniert es. Eine Tabelle mit Typ-Support wurde unten für Vollständigkeit hinzugefügt:
| Typ | Komplexität | Parameter Support | Return Value Support | Einschränkungen |
|---|---|---|---|---|
string | Simple | ✅ | ✅ | N/A |
number | Simple | ✅ | ✅ | N/A |
boolean | Simple | ✅ | ✅ | N/A |
Object | Complex | ✅ | ✅ | Objekte dürfen nur mit "Einfachen" Typen in dieser Tabelle unterstützt werden. Typen müssen in dieser Tabelle unterstützt werden. Änderungen des Prototyps werden gelöscht. Das Senden benutzerdefinierter Klassen kopiert Werte, aber nicht den Prototyp. |
Array | Complex | ✅ | ✅ | Gleiche Einschränkungen wie beim Typ Object |
Error | Complex | ✅ | ✅ | Errors that are thrown are also copied, this can result in the message and stack trace of the error changing slightly due to being thrown in a different context, and any custom properties on the Error object will be lost |
Promise | Complex | ✅ | ✅ | N/A |
Function | Complex | ✅ | ✅ | Änderungen des Prototyps werden gelöscht. Das Senden von Klassen oder Konstruktoren funktioniert nicht. |
| Cloneable Types | Simple | ✅ | ✅ | Anzeigen des verknüpften Dokuments zu Cloneable Types |
Element | Complex | ✅ | ✅ | Änderungen des Prototyps werden gelöscht. Das Senden von benutzerdefinierten Elementen funktioniert nicht. |
Blob | Complex | ✅ | ✅ | N/A |
Symbol | N/A | ❌ | ❌ | Symbole können nicht über Kontexte hinweg kopiert werden, sodass sie gelöscht werden |
Wenn der Typ, der Ihnen wichtig ist, nicht in der obigen Tabelle aufgeführt ist, wird er wahrscheinlich nicht unterstützt.
Exposing ipcRenderer
Attempting to send the entire ipcRenderer module as an object over the contextBridge will result in an empty object on the receiving side of the bridge. Sending over ipcRenderer in full can let any code send any message, which is a security footgun. To interact through ipcRenderer, provide a safe wrapper like below:
// Preload (Isolated World)
contextBridge.exposeInMainWorld('electron', {
onMyEventName: (callback) => ipcRenderer.on('MyEventName', (e, ...args) => callback(args))
})
// Renderer (Main World)
window.electron.onMyEventName(data => { /* ... */ })
Veröffentlichen von Node-Modulen und Daten
Die contextBridge kann vom Preload-Skript verwendet werden, um Ihrem Renderer Zugriff auf Node-APIs zu gewähren. Die oben gezeigte Tabelle der unterstützten Typen gilt auch für Knoten-APIs, die Sie über contextBridgeverfügbar machen. Bitte beachten Sie, dass viele Node-APIs Zugriff auf lokale Systemressourcen gewähren. Seien Sie sehr vorsichtig, welche Daten und APIs Sie im Rendererkontext, für möglicherweise fremde Ressourcen verfügbar machen.
const { contextBridge } = require('electron')
const crypto = require('node:crypto')
contextBridge.exposeInMainWorld('nodeCrypto', {
sha256sum (data) {
const hash = crypto.createHash('sha256')
hash.update(data)
return hash.digest('hex')
}
})