Перейти к основному содержанию

protocol

Регистрация пользовательского протокола и перехват существующих запросов протокола.

Process: Main

Пример реализации протокола, имеющего тот же эффект, что и протокол 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())
})
})

Примечание: Все методы, если не указано другого, могут быть использованы только после того, как событие ready модуля app будет отправлено.

Использование протокола protocol с пользовательским разделом partition или сеансом session

A protocol is registered to a specific Electron session object. Если вы не укажете сеанс, то ваш protocol будет применен сеансу по умолчанию, который использует Electron. Однако, если вы определите partition или session в браузереWindow в webPreferences, то это окно будет использовать другой сеанс, и ваш пользовательский протокол не будет работать, если вы просто используете electron.protocol.XXX.

Для того, чтобы ваш пользовательский протокол работал в сочетании с пользовательским сеансом, вам необходимо явно зарегистрировать его в этом сеансе.

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

Методы

Модуль protocol имеет следующие методы:

protocol.registerSchemesAsPrivileged(customSchemes)

Примечание: Этот метод можно использовать только до отправки события ready модуля app и может быть вызван только один раз.

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.

Пример регистрации привилегированной схемы, которая обходит Политику безопасности контента:

const { protocol } = require('electron')
protocol.registerSchemesAsPrivileged([
{ scheme: 'foo', privileges: { 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.

Регистрация схемы в качестве стандартной позволяет правильно разрешать относительные и абсолютные ресурсы при обслуживании. В противном случае схема будет вести себя как протокол file, но без возможности разрешения относительных URL-адресов.

Например, когда вы загружаете следующую страницу с помощью пользовательского протокола, не регистрируя его как стандартную схему, изображение не будет загружено, потому что нестандартные схемы не могут распознать относительные URL-адреса:

<body>
<img src='test.png'>
</body>

Registering a scheme as standard will allow access to files through the FileSystem API. В противном случае программа для схемы выдаст ошибку безопасности.

По умолчанию веб-хранилище Apis (localStorage, sessionStorage, webSQL, indexedDB, cookies) отключено для нестандартных схем. Поэтому в общем случае, если вы хотите зарегистрировать пользовательский протокол для замены протокола http, необходимо зарегистрировать его как стандартную схему.

Protocols that use streams (http and stream protocols) should set stream: true. The <video> and <audio> HTML elements expect protocols to buffer their responses by default. The stream flag configures those elements to correctly expect streaming responses.

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.

Пример:

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

History

Returns boolean - Whether the protocol was successfully registered

Регистрирует протокол scheme, который отправит файл в качестве ответа. Обработчик handler будет вызван с запросом request и обратным вызовом callback, где запрос request является входящим запросом для схемы scheme.

Для обработки запроса request, обратный вызов callback должен быть вызван либо с путём к файлу, либо с объектом, который имеет свойство path, например, callback(filePath) или callback({ path: filePath }). filePath должен быть абсолютным путем.

По умолчанию scheme обрабатывается как http:, который анализируется иначе, чем протоколы, которые следуют "общему синтаксису URI", как file:.

protocol.registerBufferProtocol(scheme, handler) Deprecated

History

Returns boolean - Whether the protocol was successfully registered

Регистрирует протокол scheme, который отправит Buffer в качестве ответа.

Использование аналогично registerFileProtocol, за исключением того, что callback должен вызываться либо с объектом Buffer, либо с объектом, имеющим свойство data.

Пример:

protocol.registerBufferProtocol('atom', (request, callback) => {
callback({ mimeType: 'text/html', data: Buffer.from('<h5>Response</h5>') })
})

protocol.registerStringProtocol(scheme, handler) Deprecated

History

Returns boolean - Whether the protocol was successfully registered

Регистрирует протокол scheme, который отправит string в качестве ответа.

Использование аналогично registerFileProtocol, за исключением того, что callback должен вызываться либо с string, либо с объектом, имеющим свойство data.

protocol.registerHttpProtocol(scheme, handler) Deprecated

History

Returns boolean - Whether the protocol was successfully registered

Регистрирует протокол scheme, который отправит HTTP-запрос в качестве ответа.

Использование аналогично registerFileProtocol, за исключением того, что callback должен быть вызван с объектом, имеющим свойство url.

protocol.registerStreamProtocol(scheme, handler) Deprecated

History

Returns boolean - Whether the protocol was successfully registered

Регистрирует протокол scheme, который отправит поток в качестве ответа.

Использование аналогично registerFileProtocol, за исключением того, что callback должен вызываться либо с объектом ReadableStream, либо с объектом, имеющим свойство data.

Пример:

const { protocol } = require('electron')
const { PassThrough } = require('stream')

function createStream (text) {
const rv = new PassThrough() // PassThrough is also a Readable stream
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>')
})
})

Возможно передать любой объект, реализующий читаемый потоковый API (выдающий data/end/error события). Например, вот как может быть возвращен файл:

protocol.registerStreamProtocol('atom', (request, callback) => {
callback(fs.createReadStream('index.html'))
})

protocol.unregisterProtocol(scheme) Deprecated

History
  • scheme string

Returns boolean - Whether the protocol was successfully unregistered

Отменяет регистрацию пользовательского протокола scheme.

protocol.isProtocolRegistered(scheme) Deprecated

History
  • scheme string

Возвращает boolean - является ли scheme уже зарегистрированной.

protocol.interceptFileProtocol(scheme, handler) Deprecated

History

Returns boolean - Whether the protocol was successfully intercepted

Перехватывает протокол scheme и использует handler в качестве нового обработчика протокола, который отправляет файл в качестве ответа.

protocol.interceptStringProtocol(scheme, handler) Deprecated

History

Returns boolean - Whether the protocol was successfully intercepted

Перехватывает протокол scheme и использует handler в качестве нового обработчика протокола, который отправляет string в качестве ответа.

protocol.interceptBufferProtocol(scheme, handler) Deprecated

History

Returns boolean - Whether the protocol was successfully intercepted

Перехватывает протокол scheme и использует handler в качестве нового обработчика протокола, который отправляет Buffer в качестве ответа.

protocol.interceptHttpProtocol(scheme, handler) Deprecated

History

Returns boolean - Whether the protocol was successfully intercepted

Перехватывает протокол scheme и использует handler в качестве нового обработчика протокола, который отправляет новый HTTP-запрос в качестве ответа.

protocol.interceptStreamProtocol(scheme, handler) Deprecated

History

Returns boolean - Whether the protocol was successfully intercepted

То же самое, что и protocol.registerStreamProtocol, за исключением того, что он заменяет существующий обработчик протокола.

protocol.uninterceptProtocol(scheme) Deprecated

History
  • scheme string

Returns boolean - Whether the protocol was successfully unintercepted

Удаляет перехватчик, установленный для scheme и восстанавливает его оригинальный обработчик.

protocol.isProtocolIntercepted(scheme) Deprecated

History
  • scheme string

Возвращает boolean - является ли scheme уже перехваченной.