Aller au contenu principal

protocol

Enregistrez un protocole personnalisé et interceptez les requêtes de protocole existantes.

Processus : Main

Un exemple d'implémentation d'un protocole qui a le même effet que le protocole file:// :

const { app, protocol, net } = require('electron')

app.whenReady().then(() => {
protocol.handle('atom', (request) =>
net.fetch('file://' + request.url.slice('atom://'.length)))
})

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.join(__dirname, filePath)).toString())
})

const mainWindow = new BrowserWindow({ webPreferences: { partition } })
})

Méthodes

Le module protocol dispose des méthodes suivantes :

protocol.registerSchemesAsPriviled(customSchemes)

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.

Registers the scheme as standard, secure, bypasses content security policy for resources, allows registering ServiceWorker, supports fetch API, streaming video/audio, and V8 code cache. Specify a privilege with the value of true to enable the capability.

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 } }
])

Un schéma standard adhère à ce que la RFC 3986 appelle la syntaxe générique de l'URI . Par exemple http et https sont des schémas standard, alors que file ne l'est pas.

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 example https or my-app. This is the bit before the : in a URL.
  • handler Function<GlobalResponse | Promise<GlobalResponse\>\>

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
})
}
})
})

See the MDN docs for Request and Response for more details.

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é

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 callbackrequest 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é

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é

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é

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é

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é

  • 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é

  • scheme string

Retourne un boolean - Indique si scheme est déjà enregistré.

protocol.interceptFileProtocol(scheme, handler) Déprécié

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é

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é

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é

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é

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é

  • 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é

  • scheme string

Retourne boolean - Indique si scheme est déjà intercepté.