メインコンテンツへ飛ぶ

protocol

カスタムプロトコルを登録し、既存のプロトコルリクエストを傍受します。

プロセス: 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())
})
})

注釈: 指定されていないすべてのメソッドは、app モジュールの ready イベントが発生した後にのみ使用できます。

protocol をカスタムの partitionsession で使用する

プロトコルは特定の Electron session オブジェクトに登録されます。 セッションを指定しない場合は、Electron が使用するデフォルトセッションに protocol が適用されます。 ただし、browserWindowwebPreferencespartition または session を定義すると、そのウィンドウに 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)

注意: このメソッドは、app モジュールの ready イベントが発行される前にのみ使用でき、一度だけ呼び出すことができます。

scheme を標準の安全なものとして登録し、リソースに対するコンテンツセキュリティポリシーをバイパスし、ServiceWorker を登録し、fetch API、video/audio のストリーミングと V8 のコードキャッシュをサポートします。 機能を有効にするには、true の値で特権を指定します。

以下はコンテンツセキュリティポリシーをバイパスする特権スキームを登録する例です。

const { protocol } = require('electron')
protocol.registerSchemesAsPrivileged([
{ scheme: 'foo', privileges: { bypassCSP: true } }
])

標準スキームは、RFC 3986 で Generic URI Syntax と呼ぶものに準拠しています。 例えば httphttps は標準スキームですが、file はそうではありません。

スキームを標準として登録することにより、サービスが提供されるときに相対的および絶対的なリソースが正しく解決されます。 そうでないと、スキームは file プロトコルのように動作しますが、相対 URL を解決することはできません。

たとえば、標準スキームとして登録せずにカスタムプロトコルで以下のページをロードすると、非標準スキームが相対URLを認識できないため、イメージはロードされません。

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

スキームを標準で登録すると、FileSystem API を介してファイルにアクセスできます。 そうしない場合、レンダラーはスキームのセキュリティエラーをスローします。

デフォルトの非標準スキームでは、ウェブストレージ API (localStorage、sessionStorage、webSQL、indexedDB、クッキー) が無効にされます。 そのため、一般的に、カスタムプロトコルを登録して http プロトコルを置き換える場合は、標準のスキームとして登録する必要があります。

(http やストリームプロトコルなどの、) ストリームを使用するプロトコルは、 stream: true を設定する必要があります。 <video><audio> HTML 要素はプロトコルがデフォルトで レスポンスをバッファすることを期待します。 stream フラグは、ストリーミング応答を期待する これらの要素を正しく設定します。

protocol.handle(scheme, handler)

  • scheme string - 処理するスキームで、例えば httpsmy-app などです。 これは URL の : の前の部分です。
  • handler Function<GlobalResponse | Promise<GlobalResponse>>

scheme のプロトコルハンドラを登録します。 このスキームが付いた URL へのリクエストはこのハンドラに委譲され、どのようなレスポンスを送るべきかが決定されます。

Response または Promise<Response> のいずれかを返せます。

サンプル:

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' }
})
}
// 注意として、これは bundle をエスケープしたパスを検証していません。例:
// 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
})
}
})
})

RequestResponse についての詳細は MDN のドキュメントをご参照ください。

protocol.unhandle(scheme)

  • scheme string - ハンドラを除去するスキーム。

protocol.handle で登録したプロトコルハンドラを除去します。

protocol.isProtocolHandled(scheme)

  • scheme string

戻り値 boolean - scheme がすでにハンドリングされているかどうか。

protocol.registerFileProtocol(scheme, handler) 非推奨

History

戻り値 boolean - protocol が正常に登録されたかどうか

ファイルをレスポンスとして送信する scheme のプロトコルを登録します。 handlerrequestcallback で呼び出されます。この requestscheme の接続リクエストです。

request を処理するには、callback を、ファイルのパスまたは path プロパティを持つオブジェクトのいずれかを使用して、例えば、callback(filePath)callback({ path: filePath }) で呼び出す必要があります。 filePath は絶対パスでなければなりません。

デフォルトでは、schemehttp: のように扱われます。これは、file: のような "Generic URI Syntax" に従うプロトコルとは違った解析がなされます。

protocol.registerBufferProtocol(scheme, handler) 非推奨

History

戻り値 boolean - protocol が正常に登録されたかどうか

Buffer をレスポンスとして送信する scheme のプロトコルを登録します。

使い方は registerFileProtocol と同じですが、 callback を、Buffer オブジェクトか data プロパティを持つオブジェクトで呼び出す必要があります。

サンプル:

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

protocol.registerStringProtocol(scheme, handler) 非推奨

History

戻り値 boolean - protocol が正常に登録されたかどうか

string をレスポンスとして送信する scheme のプロトコルを登録します。

使い方は registerFileProtocol と同じですが、 callback を、stringdata プロパティを持つオブジェクトで呼び出す必要があります。

protocol.registerHttpProtocol(scheme, handler) 非推奨

History

戻り値 boolean - protocol が正常に登録されたかどうか

HTTP リクエストをレスポンスとして送信する scheme のプロトコルを登録します。

使い方は registerFileProtocol と同じですが、 callback を、url プロパティを持つオブジェクトで呼び出す必要があります。

protocol.registerStreamProtocol(scheme, handler) 非推奨

History

戻り値 boolean - protocol が正常に登録されたかどうか

ストリームをレスポンスとして送信する scheme のプロトコルを登録します。

使い方は registerFileProtocol と同じですが、 callback を、ReadableStream オブジェクトか data プロパティを持つオブジェクトで呼び出す必要があります。

サンプル:

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

function createStream (text) {
const rv = new PassThrough() // PassThrough も ReadableStream の一種
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>')
})
})

Readable ストリーム API (data / end / error イベントが発生するもの) を実装するオブジェクトを渡すことが可能です。 例として、ファイルを返す方法を以下に示します。

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

protocol.unregisterProtocol(scheme) 非推奨

History
  • scheme string

戻り値 boolean - protocol が正常に登録解除されたかどうか

scheme のカスタムプロトコルを登録解除します。

protocol.isProtocolRegistered(scheme) 非推奨

History
  • scheme string

戻り値 boolean - scheme がすでに登録されているかどうか。

protocol.interceptFileProtocol(scheme, handler) 非推奨

History

戻り値 boolean - protocol が正常に割り込みされたかどうか

scheme プロトコルを傍受し、ファイルをレスポンスとして送信するプロトコルの新しいハンドラとして handler を使用します。

protocol.interceptStringProtocol(scheme, handler) 非推奨

History

戻り値 boolean - protocol が正常に割り込みされたかどうか

scheme プロトコルを傍受し、string をレスポンスとして送信するプロトコルの新しいハンドラとして handler を使用します。

protocol.interceptBufferProtocol(scheme, handler) 非推奨

History

戻り値 boolean - protocol が正常に割り込みされたかどうか

scheme プロトコルを傍受し、Buffer をレスポンスとして送信するプロトコルの新しいハンドラとして handler を使用します。

protocol.interceptHttpProtocol(scheme, handler) 非推奨

History

戻り値 boolean - protocol が正常に割り込みされたかどうか

scheme プロトコルを傍受し、新しい HTTP リクエストをレスポンスとして送信するプロトコルの新しいハンドラとして handler を使用します。

protocol.interceptStreamProtocol(scheme, handler) 非推奨

History

戻り値 boolean - protocol が正常に割り込みされたかどうか

protocol.registerStreamProtocol と同じですが、既存のプロトコルハンドラを置き換える点が異なります。

protocol.uninterceptProtocol(scheme) 非推奨

History
  • scheme string

戻り値 boolean - protocol が正常に割り込み解除されたかどうか

scheme のためにインストールされた傍受するハンドラを削除し、元のハンドラを復元します。

protocol.isProtocolIntercepted(scheme) 非推奨

History
  • scheme string

戻り値 boolean - scheme がすでにインターセプトされているかどうか。