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

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

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

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é

History

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

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

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

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

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

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

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

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

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