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)
apiKey
string - Das Schlüsselwort, mit dem die API inwindow
eingefügt werden soll. Die API wird aufwindow[apiKey]
zugänglich sein.api
any - Ihre API, weitere Informationen darüber, was diese API sein kann und wie sie funktioniert, finden Sie unten.
contextBridge.exposeInIsolatedWorld(worldId, apiKey, api)
worldId
Integer - The ID of the world to inject the API into.0
is the default world,999
is the world used by Electron'scontextIsolation
feature. Using 999 would expose the object for preload context. We recommend using 1000+ while creating isolated world.apiKey
string - Das Schlüsselwort, mit dem die API inwindow
eingefügt werden soll. Die API wird aufwindow[apiKey]
zugänglich sein.api
any - Ihre API, weitere Informationen darüber, was diese API sein kann und wie sie funktioniert, finden Sie unten.
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 contextBridge
verfü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')
}
})