protocol
Enregistrez un protocole personnalisé et interceptez les requêtes de protocole existantes.
Processus : Main
Un exemple d'implémentation d'un protocole ayant le même effet que le protocole file://
:
const { app, protocol, net } = require('electron')
const path = require('node:path')
const url = require('node:url')
app.whenReady().then(() => {
protocol.handle('atom', (request) => {
const filePath = request.url.slice('atom://'.length)
return net.fetch(url.pathToFileURL(path.join(__dirname, filePath)).toString())
})
})
Note: Sauf indication contraire, toutes les méthodes ne peuvent être utilisées qu’après l’émission de l'événement ready
du module app
.
Utilisation de protocol
avec une partition
ou session
personnalisée
Un protocole est enregistré pour un objet Electron spécifique session
. Si vous ne spécifiez pas de session, votre protocol
sera appliquée à la session utilisée par défaut dans Electron. Toutefois, si vous définissez une partition
ou une session
dans les webPreferences
de votre browserWindow
, cette fenêtre utilisera une session différente et votre protocole personnalisé ne fonctionnera pas si vous utilisez simplement electron.protocol.XXX
.
Afin que votre protocole personnalisé fonctionne en combinaison avec une session personnalisée, vous devez l'enregistrer explicitement pour celle-ci.
const { app, BrowserWindow, net, protocol, session } = require('electron')
const path = require('node:path')
const url = require('url')
app.whenReady().then(() => {
const partition = 'persist:example'
const ses = session.fromPartition(partition)
ses.protocol.handle('atom', (request) => {
const filePath = request.url.slice('atom://'.length)
return net.fetch(url.pathToFileURL(path.resolve(__dirname, filePath)).toString())
})
const mainWindow = new BrowserWindow({ webPreferences: { partition } })
})
Méthodes
Le module protocol
dispose des méthodes suivantes :
protocol.registerSchemesAsPriviled(customSchemes)
customSchemes
CustomScheme[]
Note: Cette méthode ne peut être utilisée qu'avant l'événement ready
du app
est émis et ne peut être appelé qu'une seule fois.
Enregistre le scheme
comme schéma standard, sécurisé et contournant la politique de sécurité du contenu pour les ressources, permettant aussi d’enregistrer ServiceWorker, la prise en charge de l'API fetch , le streaming vidéo/audio et le cache de code V8. Afin de spécifier un privilège il faut mettre sa valeur à true
pour activer la fonctionnalité.
L'exemple suivant illustre l'enregistrement d'un schéma privilégié, contournant la politique de sécurité du contenu :
const { protocol } = require('electron')
protocol.registerSchemesAsPrivileged([
{ scheme: 'foo', privilèges: { bypassCSP: true } }
])
A standard scheme adheres to what RFC 3986 calls generic URI syntax. For example http
and https
are standard schemes, while file
is not.
L'enregistrement d'un schéma en tant que standard, permet de résoudre correcteement les ressources relatives et absolues quand elles sont servies. Sinon, le schéma se comportera comme le protocole fichier
, mais sans la possibilité de résoudre les URL relatives.
Par exemple lorsque vous chargez la page suivante avec un protocole personnalisé sans l'enregistrer en tant que schéma standard, l'image ne sera pas chargée car les schémas non standards ne peuvent pas reconnaître les URL relatives :
<body>
<img src='test.png'>
</body>
L'enregistrement d'un schéma en tant que standard permettra l'accès aux fichiers via l'API FileSystem API. Sinon, le moteur de rendu lancera une erreur de sécurité pour le schéma.
Par défaut les apis de stockage web (localStorage, sessionStorage, webSQL, indexedDB, cookies) sont désactivés pour les schémas non standard. Donc, en général si vous voulez enregistrer un protocole personnalisé pour remplacer le protocole http
, vous devez l'enregistrer en tant que schéma standard.
Les protocoles qui utilisent les flux (protocoles http et stream) doivent déclarerstream: true
. Les éléments HTML <video>
et <audio>
s'attendent à ce que les protocoles mettent par défaut leurs réponses en mémoire tampon. L’indicateur stream
configure ces éléments pour qu’ils s’attendent correctement à recevoir des réponses de type stream.
protocol.handle(scheme, handler)
scheme
string - scheme to handle, for examplehttps
ormy-app
. This is the bit before the:
in a URL.handler
Function<GlobalResponse | Promise<GlobalResponse>>request
GlobalRequest
Register a protocol handler for scheme
. Requests made to URLs with this scheme will delegate to this handler to determine what response should be sent.
Either a Response
or a Promise<Response>
can be returned.
Exemple :
const { app, net, protocol } = require('electron')
const path = require('node:path')
const { pathToFileURL } = require('url')
protocol.registerSchemesAsPrivileged([
{
scheme: 'app',
privileges: {
standard: true,
secure: true,
supportFetchAPI: true
}
}
])
app.whenReady().then(() => {
protocol.handle('app', (req) => {
const { host, pathname } = new URL(req.url)
if (host === 'bundle') {
if (pathname === '/') {
return new Response('<h1>hello, world</h1>', {
headers: { 'content-type': 'text/html' }
})
}
// NB, this checks for paths that escape the bundle, e.g.
// app://bundle/../../secret_file.txt
const pathToServe = path.resolve(__dirname, pathname)
const relativePath = path.relative(__dirname, pathToServe)
const isSafe = relativePath && !relativePath.startsWith('..') && !path.isAbsolute(relativePath)
if (!isSafe) {
return new Response('bad', {
status: 400,
headers: { 'content-type': 'text/html' }
})
}
return net.fetch(pathToFileURL(pathToServe).toString())
} else if (host === 'api') {
return net.fetch('https://api.my-server.com/' + pathname, {
method: req.method,
headers: req.headers,
body: req.body
})
}
})
})
Voir les docs MDN de Request
et Response
pour plus de détails.
protocol.unhandle(scheme)
scheme
string - scheme for which to remove the handler.
Removes a protocol handler registered with protocol.handle
.
protocol.isProtocolHandled(scheme)
scheme
string
Returns boolean
- Whether scheme
is already handled.
protocol.registerFileProtocol(scheme, handler)
Déprécié
History
scheme
string- Fonction
handler
request
ProtocolRequestcallback
Functionresponse
(string | ProtocolResponse)
Retourne boolean
- Indique si le protocole a été enregistré avec succès
Enregistre un protocole suivant scheme
qui enverra un fichier comme réponse. Le handler
sera appelé avec request
et callback
où request
est une requête entrante pour le scheme
.
Pour gérer la requête
, la callback
doit être appelée soit avec le chemin du fichier, soit avec un objet qui a une propriété chemin
. . callback(filePath)
ou callback({ path: filePath })
. Le filePath
doit être un chemin absolu.
Par défaut, le scheme
est traité comme http:
, qui est analysé différemment des protocoles qui suivent la "syntaxe URI générique" comme file:
.
protocol.registerBufferProtocol(scheme, handler)
Déprécié
History
scheme
string- Fonction
handler
request
ProtocolRequestcallback
Functionresponse
(Buffer| ProtocolResponse)
Retourne boolean
- Indique si le protocole a été enregistré avec succès
Enregistre un protocole de schéma
qui enverra un Buffer
en tant que réponse.
L'utilisation est la même qu'avec registerFileProtocol
, sauf que la callback
doit être appelée avec un objet Buffer
ou un objet ayant la propriété data
.
Exemple :
protocol.registerBufferProtocol('atom', (request, callback) => {
callback({ mimeType: 'text/html', data: Buffer.from('<h5>Response</h5>') })
})
protocol.registerStringProtocol(scheme, handler)
Déprécié
History
scheme
string- Fonction
handler
request
ProtocolRequestcallback
Functionresponse
(string | ProtocolResponse)
Retourne boolean
- Indique si le protocole a été enregistré avec succès
Enregistre un protocole de schéma
qui enverra une string
en tant que réponse.
L'utilisation est la même qu'avec registerFileProtocol
, sauf que la callback
doit être appelée soit avec un objet de type string
soit avec un objet ayant la propriété data
.
protocol.registerHttpProtocol(scheme, handler)
Déprécié
History
scheme
string- Fonction
handler
request
ProtocolRequestcallback
Functionresponse
ProtocolResponse
Retourne boolean
- Indique si le protocole a été enregistré avec succès
Enregistre un protocole de schéma
qui enverra une requête HTTP en réponse.
L'utilisation est la même qu'avec registerFileProtocol
, sauf que la callback
doit être appelé avec un objet ayant la propriété url
.
protocol.registerStreamProtocol(scheme, handler)
Déprécié
History
scheme
string- Fonction
handler
request
ProtocolRequestcallback
Functionresponse
(ReadableStream | ProtocolResponse)
Retourne boolean
- Indique si le protocole a été enregistré avec succès
Enregistre un protocole suivant scheme
qui enverra un flux en tant que réponse.
L'utilisation est la même qu'avec registerFileProtocol
, sauf que la callback
doit être appelée soit avec un objet de type ReadableStream
soit avec un objet ayant la propriété data
.
Exemple :
const { protocol } = require('electron')
const { PassThrough } = require('stream')
function createStream (text) {
const rv = new PassThrough() // PassThrough est aussi un stream Readable
rv.push(text)
rv.push(null)
return rv
}
protocol.registerStreamProtocol('atom', (request, callback) => {
callback({
statusCode: 200,
headers: {
'content-type': 'text/html'
},
data: createStream('<h5>Response</h5>')
})
})
Il est possible de passer n'importe quel objet implémentant l'API de flux readable (et qui émet donc les évènements data
/end
/error
). Par exemple, voici comment un fichier peut être retourné :
protocol.registerStreamProtocol('atom', (request, callback) => {
callback(fs.createReadStream('index.html'))
})
protocol.unregisterProtocol(scheme)
Déprécié
History
scheme
string
Retourne un boolean
- Indique si l'enregistrement du protocole a été supprimé avec succès
Enregistre le protocole personnalisé de schéma
.
protocol.isProtocolRegistered(scheme)
Déprécié
History
scheme
string
Retourne un boolean
- Indique si scheme
est déjà enregistré.
protocol.interceptFileProtocol(scheme, handler)
Déprécié
History
scheme
string- Fonction
handler
request
ProtocolRequestcallback
Functionresponse
(string | ProtocolResponse)
Retourne boolean
- Indique si le protocole a été intercepté avec succès
Intercepte le protocole schéma
et utilise handler
comme nouveau gestionnaire du protocole, qui envoie un fichier comme réponse.
protocol.interceptStringProtocol(scheme, handler)
Déprécié
History
scheme
string- Fonction
handler
request
ProtocolRequestcallback
Functionresponse
(string | ProtocolResponse)
Retourne boolean
-Indique si le protocole a été intercepté avec succès
Intercepte le protocole schéma
et utilise handler
comme nouveau gestionnaire du protocole, qui envoie une string
comme réponse.
protocol.interceptBufferProtocol(scheme, handler)
Déprécié
History
scheme
string- Fonction
handler
request
ProtocolRequestcallback
Functionresponse
(Buffer| ProtocolResponse)
Retourne boolean
-Indique si le protocole a été intercepté avec succès
Intercepte le protocole schéma
et utilise handler
comme nouveau gestionnaire du protocole, qui envoie un Buffer
comme réponse.
protocol.interceptHttpProtocol(scheme, handler)
Déprécié
History
scheme
string- Fonction
handler
request
ProtocolRequestcallback
Functionresponse
ProtocolResponse
Retourne boolean
-Indique si le protocole a été intercepté avec succès
Intercepte le protocole schéma
et utilise handler
comme nouveau gestionnaire du protocole, qui envoie une nouvelle requête HTTP comme réponse.
protocol.interceptStreamProtocol(scheme, handler)
Déprécié
History
scheme
string- Fonction
handler
request
ProtocolRequestcallback
Functionresponse
(ReadableStream | ProtocolResponse)
Retourne boolean
-Indique si le protocole a été intercepté avec succès
Identique à protocol.registerStreamProtocol
, excepté qu'il remplace un gestionnaire de protocole existant.
protocol.uninterceptProtocol(scheme)
Déprécié
History
scheme
string
Retourne boolean
- Si l'interception du protocole a été supprimé avec succès
Supprime l'intercepteur installé pour scheme
et restaure son gestionnaire d'origine.
protocol.isProtocolIntercepted(scheme)
Déprécié
History
scheme
string
Retourne boolean
- Indique si scheme
est déjà intercepté.