protocol
注册自定义协议并拦截现有协议请求。
¥Register a custom protocol and intercept existing protocol requests.
进程:主进程
¥Process: Main
实现与 file://
协议具有相同效果的协议的示例:
¥An example of implementing a protocol that has the same effect as the
file://
protocol:
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
事件发出后使用。
¥Note: All methods unless specified can only be used after the ready
event
of the app
module gets emitted.
将 protocol
与自定义 partition
或 session
结合使用
¥Using protocol
with a custom partition
or session
协议被注册到特定的 Electron session
对象。如果你没有指定会话,那么你的 protocol
将应用于 Electron 使用的默认会话。但是,如果你在 browserWindow
的 webPreferences
上定义了 partition
或 session
,那么该窗口将使用不同的会话,并且如果你只使用 electron.protocol.XXX
,你的自定义协议将不起作用。
¥A protocol is registered to a specific Electron session
object. If you don't specify a session, then your protocol
will be applied to
the default session that Electron uses. However, if you define a partition
or
session
on your browserWindow
's webPreferences
, then that window will use
a different session and your custom protocol will not work if you just use
electron.protocol.XXX
.
要让自定义协议与自定义会话结合使用,你需要将其显式注册到该会话。
¥To have your custom protocol work in combination with a custom session, you need to register it to that session explicitly.
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 } })
})
方法
¥Methods
protocol
模块有以下方法:
¥The protocol
module has the following methods:
protocol.registerSchemesAsPrivileged(customSchemes)
customSchemes
CustomScheme[]
注意:该方法只能在 app
模块的 ready
事件发出之前使用,并且只能调用一次。
¥Note: This method can only be used before the ready
event of the app
module gets emitted and can be called only once.
将 scheme
注册为标准、安全,绕过资源的内容安全策略,允许注册 ServiceWorker,支持 fetch API、流视频/音频和 V8 代码缓存。指定值为 true
的权限以启用该功能。
¥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.
注册绕过内容安全策略的特权方案的示例:
¥An example of registering a privileged scheme, that bypasses Content Security Policy:
const { protocol } = require('electron')
protocol.registerSchemesAsPrivileged([
{ scheme: 'foo', privileges: { bypassCSP: true } }
])
标准方案遵循 RFC 3986 所谓的 通用 URI 语法。例如 http
和 https
是标准方案,而 file
不是。
¥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。
¥Registering a scheme as standard allows relative and absolute resources to
be resolved correctly when served. Otherwise the scheme will behave like the
file
protocol, but without the ability to resolve relative URLs.
例如,当你使用自定义协议加载以下页面而不将其注册为标准方案时,将不会加载图片,因为非标准方案无法识别相对 URL:
¥For example when you load following page with custom protocol without registering it as standard scheme, the image will not be loaded because non-standard schemes can not recognize relative URLs:
<body>
<img src='test.png'>
</body>
将方案注册为标准将允许通过 文件系统 API 访问文件。否则渲染器将抛出该方案的安全错误。
¥Registering a scheme as standard will allow access to files through the FileSystem API. Otherwise the renderer will throw a security error for the scheme.
默认情况下,非标准方案禁用 Web 存储 api(localStorage、sessionStorage、webSQL、indexedDB、cookie)。所以一般来说如果你想注册一个自定义协议来替代 http
协议,你必须将其注册为标准方案。
¥By default web storage apis (localStorage, sessionStorage, webSQL, indexedDB,
cookies) are disabled for non standard schemes. So in general if you want to
register a custom protocol to replace the http
protocol, you have to register
it as a standard scheme.
使用流的协议(http 和流协议)应设置 stream: true
。<video>
和 <audio>
HTML 元素期望协议默认缓冲它们的响应。stream
标志配置这些元素以正确期望流响应。
¥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
字符串 - 要处理的方案,例如https
或my-app
。这是 URL 中:
之前的位。¥
scheme
string - scheme to handle, for examplehttps
ormy-app
. This is the bit before the:
in a URL. -
handler
Function<GlobalResponse | Promise<GlobalResponse>>request
GlobalRequest
为 scheme
注册协议处理程序。使用此方案向 URL 发出的请求将委托给此处理程序来确定应发送什么响应。
¥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.
可以返回 Response
或 Promise<Response>
。
¥Either a Response
or a Promise<Response>
can be returned.
示例:
¥Example:
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
})
}
})
})
有关更多详细信息,请参阅 Request
和 Response
的 MDN 文档。
¥See the MDN docs for Request
and Response
for more details.
protocol.unhandle(scheme)
-
scheme
字符串 - 要删除处理程序的方案。¥
scheme
string - scheme for which to remove the handler.
删除使用 protocol.handle
注册的协议处理程序。
¥Removes a protocol handler registered with protocol.handle
.
protocol.isProtocolHandled(scheme)
-
scheme
字符串¥
scheme
string
返回 boolean
- scheme
是否已处理。
¥Returns boolean
- Whether scheme
is already handled.
protocol.registerFileProtocol(scheme, handler)
已弃用
¥protocol.registerFileProtocol(scheme, handler)
Deprecated
History
-
scheme
字符串¥
scheme
string -
handler
函数¥
handler
Function-
request
ProtocolRequest -
callback
函数¥
callback
Functionresponse
(string | ProtocolResponse)
-
返回 boolean
- 协议是否注册成功
¥Returns boolean
- Whether the protocol was successfully registered
注册 scheme
协议,该协议将发送文件作为响应。handler
将通过 request
和 callback
进行调用,其中 request
是对 scheme
的传入请求。
¥Registers a protocol of scheme
that will send a file as the response. The
handler
will be called with request
and callback
where request
is
an incoming request for the scheme
.
要处理 request
,应使用文件路径或具有 path
属性的对象(例如 callback(filePath)
或 callback({ path: filePath })
。filePath
必须是绝对路径。
¥To handle the request
, the callback
should be called with either the file's
path or an object that has a path
property, e.g. callback(filePath)
or
callback({ path: filePath })
. The filePath
must be an absolute path.
默认情况下,scheme
被视为与 http:
类似,其解析方式与遵循 "通用 URI 语法"(如 file:
)的协议不同。
¥By default the scheme
is treated like http:
, which is parsed differently
from protocols that follow the "generic URI syntax" like file:
.
protocol.registerBufferProtocol(scheme, handler)
已弃用
¥protocol.registerBufferProtocol(scheme, handler)
Deprecated
History
-
scheme
字符串¥
scheme
string -
handler
函数¥
handler
Function-
request
ProtocolRequest -
callback
函数¥
callback
Functionresponse
(Buffer | ProtocolResponse)
-
返回 boolean
- 协议是否注册成功
¥Returns boolean
- Whether the protocol was successfully registered
注册 scheme
协议,该协议将发送 Buffer
作为响应。
¥Registers a protocol of scheme
that will send a Buffer
as a response.
用法与 registerFileProtocol
相同,只是 callback
应该使用 Buffer
对象或具有 data
属性的对象来调用。
¥The usage is the same with registerFileProtocol
, except that the callback
should be called with either a Buffer
object or an object that has the data
property.
示例:
¥Example:
protocol.registerBufferProtocol('atom', (request, callback) => {
callback({ mimeType: 'text/html', data: Buffer.from('<h5>Response</h5>') })
})
protocol.registerStringProtocol(scheme, handler)
已弃用
¥protocol.registerStringProtocol(scheme, handler)
Deprecated
History
-
scheme
字符串¥
scheme
string -
handler
函数¥
handler
Function-
request
ProtocolRequest -
callback
函数¥
callback
Functionresponse
(string | ProtocolResponse)
-
返回 boolean
- 协议是否注册成功
¥Returns boolean
- Whether the protocol was successfully registered
注册 scheme
协议,该协议将发送 string
作为响应。
¥Registers a protocol of scheme
that will send a string
as a response.
用法与 registerFileProtocol
相同,只是 callback
应该使用 string
或具有 data
属性的对象来调用。
¥The usage is the same with registerFileProtocol
, except that the callback
should be called with either a string
or an object that has the data
property.
protocol.registerHttpProtocol(scheme, handler)
已弃用
¥protocol.registerHttpProtocol(scheme, handler)
Deprecated
History
-
scheme
字符串¥
scheme
string -
handler
函数¥
handler
Function-
request
ProtocolRequest -
callback
函数¥
callback
Functionresponse
ProtocolResponse
-
返回 boolean
- 协议是否注册成功
¥Returns boolean
- Whether the protocol was successfully registered
注册 scheme
协议,该协议将发送 HTTP 请求作为响应。
¥Registers a protocol of scheme
that will send an HTTP request as a response.
用法与 registerFileProtocol
相同,只是 callback
应该使用具有 url
属性的对象来调用。
¥The usage is the same with registerFileProtocol
, except that the callback
should be called with an object that has the url
property.
protocol.registerStreamProtocol(scheme, handler)
已弃用
¥protocol.registerStreamProtocol(scheme, handler)
Deprecated
History
-
scheme
字符串¥
scheme
string -
handler
函数¥
handler
Function-
request
ProtocolRequest -
callback
函数¥
callback
Functionresponse
(ReadableStream | ProtocolResponse)
-
返回 boolean
- 协议是否注册成功
¥Returns boolean
- Whether the protocol was successfully registered
注册 scheme
协议,该协议将发送流作为响应。
¥Registers a protocol of scheme
that will send a stream as a response.
用法与 registerFileProtocol
相同,只是 callback
应该使用 ReadableStream
对象或具有 data
属性的对象来调用。
¥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.
示例:
¥Example:
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
事件)。例如,返回文件的方式如下:
¥It is possible to pass any object that implements the readable stream API (emits
data
/end
/error
events). For example, here's how a file could be returned:
protocol.registerStreamProtocol('atom', (request, callback) => {
callback(fs.createReadStream('index.html'))
})
protocol.unregisterProtocol(scheme)
已弃用
¥protocol.unregisterProtocol(scheme)
Deprecated
History
-
scheme
字符串¥
scheme
string
返回 boolean
- 协议是否成功注销
¥Returns boolean
- Whether the protocol was successfully unregistered
注销 scheme
的自定义协议。
¥Unregisters the custom protocol of scheme
.
protocol.isProtocolRegistered(scheme)
已弃用
¥protocol.isProtocolRegistered(scheme)
Deprecated
History
-
scheme
字符串¥
scheme
string
返回 boolean
- scheme
是否已经注册。
¥Returns boolean
- Whether scheme
is already registered.
protocol.interceptFileProtocol(scheme, handler)
已弃用
¥protocol.interceptFileProtocol(scheme, handler)
Deprecated
History
-
scheme
字符串¥
scheme
string -
handler
函数¥
handler
Function-
request
ProtocolRequest -
callback
函数¥
callback
Functionresponse
(string | ProtocolResponse)
-
返回 boolean
- 协议是否被成功拦截
¥Returns boolean
- Whether the protocol was successfully intercepted
拦截 scheme
协议并使用 handler
作为该协议的新处理程序,该处理程序发送文件作为响应。
¥Intercepts scheme
protocol and uses handler
as the protocol's new handler
which sends a file as a response.
protocol.interceptStringProtocol(scheme, handler)
已弃用
¥protocol.interceptStringProtocol(scheme, handler)
Deprecated
History
-
scheme
字符串¥
scheme
string -
handler
函数¥
handler
Function-
request
ProtocolRequest -
callback
函数¥
callback
Functionresponse
(string | ProtocolResponse)
-
返回 boolean
- 协议是否被成功拦截
¥Returns boolean
- Whether the protocol was successfully intercepted
拦截 scheme
协议并使用 handler
作为该协议的新处理程序,该处理程序发送 string
作为响应。
¥Intercepts scheme
protocol and uses handler
as the protocol's new handler
which sends a string
as a response.
protocol.interceptBufferProtocol(scheme, handler)
已弃用
¥protocol.interceptBufferProtocol(scheme, handler)
Deprecated
History
-
scheme
字符串¥
scheme
string -
handler
函数¥
handler
Function-
request
ProtocolRequest -
callback
函数¥
callback
Functionresponse
(Buffer | ProtocolResponse)
-
返回 boolean
- 协议是否被成功拦截
¥Returns boolean
- Whether the protocol was successfully intercepted
拦截 scheme
协议并使用 handler
作为该协议的新处理程序,该处理程序发送 Buffer
作为响应。
¥Intercepts scheme
protocol and uses handler
as the protocol's new handler
which sends a Buffer
as a response.
protocol.interceptHttpProtocol(scheme, handler)
已弃用
¥protocol.interceptHttpProtocol(scheme, handler)
Deprecated
History
-
scheme
字符串¥
scheme
string -
handler
函数¥
handler
Function-
request
ProtocolRequest -
callback
函数¥
callback
Functionresponse
ProtocolResponse
-
返回 boolean
- 协议是否被成功拦截
¥Returns boolean
- Whether the protocol was successfully intercepted
拦截 scheme
协议并使用 handler
作为该协议的新处理程序,该处理程序发送新的 HTTP 请求作为响应。
¥Intercepts scheme
protocol and uses handler
as the protocol's new handler
which sends a new HTTP request as a response.
protocol.interceptStreamProtocol(scheme, handler)
已弃用
¥protocol.interceptStreamProtocol(scheme, handler)
Deprecated
History
-
scheme
字符串¥
scheme
string -
handler
函数¥
handler
Function-
request
ProtocolRequest -
callback
函数¥
callback
Functionresponse
(ReadableStream | ProtocolResponse)
-
返回 boolean
- 协议是否被成功拦截
¥Returns boolean
- Whether the protocol was successfully intercepted
与 protocol.registerStreamProtocol
相同,只是它替换了现有的协议处理程序。
¥Same as protocol.registerStreamProtocol
, except that it replaces an existing
protocol handler.
protocol.uninterceptProtocol(scheme)
已弃用
¥protocol.uninterceptProtocol(scheme)
Deprecated
History
-
scheme
字符串¥
scheme
string
返回 boolean
- 协议是否成功未被拦截
¥Returns boolean
- Whether the protocol was successfully unintercepted
删除为 scheme
安装的拦截器并恢复其原始处理程序。
¥Remove the interceptor installed for scheme
and restore its original handler.
protocol.isProtocolIntercepted(scheme)
已弃用
¥protocol.isProtocolIntercepted(scheme)
Deprecated
History
-
scheme
字符串¥
scheme
string
返回 boolean
- scheme
是否已被拦截。
¥Returns boolean
- Whether scheme
is already intercepted.