Aller au contenu principal

protocol

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

Process: 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] All methods unless specified can only be used after the ready event of the app module gets emitted.

Utilisation de protocol avec une partition ou session personnalisée

A protocol is registered to a specific Electron session object. 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] This method can only be used before the ready event of the app module gets emitted and can be called only once.

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>

Registering a scheme as standard will allow access to files through the 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. The <video> and <audio> HTML elements expect protocols to buffer their responses by default. 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é

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.

The usage is the same with registerFileProtocol, except that the callback should be called with either a ReadableStream object or an object that has the data property.

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