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
をカスタムの partition
や session
で使用する
プロトコルは特定の Electron session
オブジェクトに登録されます。 セッションを指定しない場合は、Electron が使用するデフォルトセッションに protocol
が適用されます。 ただし、browserWindow
の webPreferences
に partition
または 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)
customSchemes
CustomScheme[]
注意: このメソッドは、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 と呼ぶものに準拠しています。 例えば http
と https
は標準スキームですが、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 - 処理するスキームで、例えばhttps
やmy-app
などです。 これは URL の:
の前の部分です。handler
Function<GlobalResponse | Promise<GlobalResponse>>request
GlobalRequest
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
})
}
})
})
Request
と Response
についての詳細は MDN のドキュメントをご参照ください。
protocol.unhandle(scheme)
scheme
string - ハンドラを除去するスキーム。
protocol.handle
で登録したプロトコルハンドラを除去します。
protocol.isProtocolHandled(scheme)
scheme
string
戻り値 boolean
- scheme
がすでにハンドリングされているかどうか。
protocol.registerFileProtocol(scheme, handler)
非推奨
History
scheme
stringhandler
Functionrequest
ProtocolRequestcallback
Functionresponse
(string | ProtocolResponse)
戻り値 boolean
- protocol が正常に登録されたかどうか
ファイルをレスポンスとして送信する scheme
のプロトコルを登録します。 handler
は request
と callback
で呼び出されます。この request
は scheme
の接続リクエストです。
request
を処理するには、callback
を、ファイルのパスまたは path
プロパティを持つオブジェクトのいずれかを使用して、例えば、callback(filePath)
や callback({ path: filePath })
で呼び出す必要があります。 filePath
は絶対パスでなければなりません。
デフォルトでは、scheme
は http:
のように扱われます。これは、file:
のような "Generic URI Syntax" に従うプロトコルとは違った解析がなされます。
protocol.registerBufferProtocol(scheme, handler)
非推奨
History
scheme
stringhandler
Functionrequest
ProtocolRequestcallback
Functionresponse
(Buffer | ProtocolResponse)
戻り値 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
scheme
stringhandler
Functionrequest
ProtocolRequestcallback
Functionresponse
(string | ProtocolResponse)
戻り値 boolean
- protocol が正常に登録されたかどうか
string
をレスポンスとして送信する scheme
のプロトコルを登録します。
使い方は registerFileProtocol
と同じですが、 callback
を、string
か data
プロパティを持つオブジェクトで呼び出す必要があります。
protocol.registerHttpProtocol(scheme, handler)
非推奨
History
scheme
stringhandler
Functionrequest
ProtocolRequestcallback
Functionresponse
ProtocolResponse
戻り値 boolean
- protocol が正常に登録されたかどうか
HTTP リクエストをレスポンスとして送信する scheme
のプロトコルを登録します。
使い方は registerFileProtocol
と同じですが、 callback
を、url
プロパティを持つオブジェクトで呼び出す必要があります。
protocol.registerStreamProtocol(scheme, handler)
非推奨
History
scheme
stringhandler
Functionrequest
ProtocolRequestcallback
Functionresponse
(ReadableStream | ProtocolResponse)
戻り値 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
scheme
stringhandler
Functionrequest
ProtocolRequestcallback
Functionresponse
(string | ProtocolResponse)
戻り値 boolean
- protocol が正常に割り込みされたかどうか
scheme
プロトコルを傍受し、ファイルをレスポンスとして送信するプロトコルの新しいハンドラとして handler
を使用します。
protocol.interceptStringProtocol(scheme, handler)
非推奨
History
scheme
stringhandler
Functionrequest
ProtocolRequestcallback
Functionresponse
(string | ProtocolResponse)
戻り値 boolean
- protocol が正常に割り込みされたかどうか
scheme
プロトコルを傍受し、string
をレスポンスとして送信するプロトコルの新しいハンドラとして handler
を使用します。
protocol.interceptBufferProtocol(scheme, handler)
非推奨
History
scheme
stringhandler
Functionrequest
ProtocolRequestcallback
Functionresponse
(Buffer | ProtocolResponse)
戻り値 boolean
- protocol が正常に割り込みされたかどうか
scheme
プロトコルを傍受し、Buffer
をレスポンスとして送信するプロトコルの新しいハンドラとして handler
を使用します。