Copyright © 2024 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
推送 API 允许通过 推送消息 将信息发送到 Web 应用程序, 该操作通过 推送服务 实现。 应用服务器 可以在任何时候发送 推送消息, 即使 Web 应用程序或 用户代理 处于非活动状态。 推送服务 确保推送消息可靠且高效地传递到 用户代理。 推送消息 被传送到在 Web 应用程序源中运行的 Service Worker, 该 Service Worker 可以使用消息中的信息来更新本地状态或向用户显示通知。
本节描述了本文档在发布时的状态。当前 W3C 出版物的列表以及本技术报告的最新修订版可在 W3C 技术报告索引中找到, 地址为 https://www.w3.org/TR/。
本文档由 Web 应用工作组 作为工作草案发布, 并采用了 推荐流程。
作为工作草案发布并不意味着 W3C 及其成员的认可。
这是一个草案文档,可能会随时更新、替换或被其他文档废弃。在引用此文档时,除了作为进行中的工作外,不应作为其他用途引用。
本文档由一个遵循 W3C 专利政策 的小组制作。W3C 维护了 与本小组成果相关的专利披露公开列表, 该页面还包括披露专利的说明。任何知晓可能包含 基本声明 的专利的个人,必须按照 W3C 专利政策 第6节披露该信息。
本文档受 2023年11月3日 W3C 流程文档 管辖。
本节为非规范性内容。
推送 API 允许 Web 应用程序与 用户代理 异步通信。 这使得 应用服务器 可以在掌握时间敏感信息时, 向 用户代理 提供这些信息,而无需等待用户打开 Web 应用程序。
特别地,推送消息 即使在 Web 应用程序当前没有在浏览器窗口中运行时也会被传送: 这与用户关闭 Web 应用程序但仍能从应用程序接收消息的情况相关。 例如,当接收到 推送消息 时,Web 应用程序可能会被重新启动, 例如推送消息可能用于通知用户有 WebRTC 来电。
当 用户代理 暂时离线时,也可以发送 推送消息。 为了支持这一点,推送服务 会存储消息,直到 用户代理 可用为止。 这支持了用户离线时 web 应用程序获知变更的用例,并确保 用户代理 能够及时获得相关信息。推送消息 由 推送服务 存储,直到 用户代理 可访问并可以传递消息。
当 用户代理 正在积极使用 Web 应用程序时,推送 API 也会确保推送消息的可靠传递, 例如用户正在积极使用 Web 应用程序,或 Web 应用程序通过活动的 worker、框架或后台窗口与 应用服务器 进行通信时。 这并不是推送 API 的主要使用场景。 Web 应用程序可能选择使用推送 API 发送不频繁的消息,以避免与 应用服务器 保持持续通信。
推送消息适合于用户代理与 Web 应用程序之间尚未建立活动通信通道的场合。 与通过 Fetch API 或 [WebSockets] 等更直接的通信方法相比,发送 推送消息 需要消耗更多资源。 推送消息 通常具有比直接通信更高的延迟,并且可能受到使用限制。 大多数 推送服务 会限制可以发送的 推送消息 的大小和数量。
Web 推送协议 [RFC8030] 描述了一种协议,该协议使 用户代理 或 应用服务器 能够与 推送服务 通信。 也可以使用其他协议来替代该协议,但本规范假定使用此协议;其他协议应提供兼容的语义。
Content-Encoding
HTTP 头部,描述于
[RFC7231] 的第3.1.2.2节,
指示应用于 推送消息 的内容编码。
应用服务器 指的是 Web 应用程序的服务器端组件。
推送消息 是从 应用服务器 发送到 Web 应用程序的数据。
当消息提交给 推送订阅 时,推送消息会传送给与其关联的 活动 worker。 如果 service worker 当前未运行,则会启动该 worker 以传递消息。
推送订阅 是在 用户代理 和代表 Web 应用程序的 推送服务 之间建立的消息传递上下文。 每个 推送订阅 都与一个 service worker 注册 关联, 并且一个 service worker 注册 最多只能有一个 推送订阅。
一个 推送订阅 关联了一个 推送端点。它 必须 是由 推送服务 暴露的绝对 URL,应用服务器可在该处发送 推送消息。推送端点 必须 唯一标识该 推送订阅。
一个 推送订阅 可以 具有关联的 订阅到期时间。如果设置了该时间,则它 必须 表示自1970年1月1日00:00:00 UTC以来的毫秒数, 到该时间点订阅将被 停用。 用户代理 应该 尝试在订阅到期前 刷新 该推送订阅。
一个 推送订阅 具有用于 P-256 ECDH 密钥对和身份验证密钥的内部槽, 根据 [RFC8291]。这些槽在创建 推送订阅 时 必须 被填充。
如果 用户代理 出于任何原因需要更改密钥,则它 必须
触发 "pushsubscriptionchange
"
事件,
该事件应与 service worker 注册
关联,
该注册与拥有旧密钥的 oldSubscription 实例和拥有新密钥的 newSubscription 实例关联的
PushSubscription
实例表示。
若要 创建推送订阅,给定 optionsDictionary:
PushSubscription
。
PushSubscriptionOptions
对象,并用 optionsDictionary 的相应成员和值初始化其属性。
options
属性设置为 options。
getKey
()
方法,并传递 "p256dh
" 作为参数来检索。
getKey
()
方法并传递 "auth
" 作为参数来检索该密钥。
applicationServerKey
属性时,请求中应包括该属性。重抛任何异常。
endpoint
属性设置为该
推送订阅 的 推送端点。
expirationTime
属性。
用户代理 或 推送服务 可以 选择随时刷新(refresh)推送订阅,例如因为其已达到某个年龄。
当这种情况发生时,用户代理 必须 根据为创建当前 推送订阅 提供的 PushSubscriptionOptions
执行 创建推送订阅 的步骤。新的 推送订阅 必须 拥有一个与原始订阅不同的密钥对。
成功后,用户代理 必须 触发“pushsubscriptionchange
”事件,
其中 service worker
注册与 推送订阅 关联,registration 表示最初的 推送订阅 的 PushSubscription
实例为
oldSubscription,
新的 推送订阅 的 PushSubscription
实例为
newSubscription。
为了提供足够的时间将更改传播到 应用服务器,用户代理 可以 在刷新后的一段时间内继续接受来自旧推送订阅的消息。 一旦为刷新后的推送订阅 接收到消息,所有旧的推送订阅 必须 被停用。
如果 用户代理 无法刷新 推送订阅,则 应 定期重试刷新。
当 推送订阅 无法再使用时,例如它已过期,用户代理 必须 触发“pushsubscriptionchange
”事件,
其中 service worker
注册与 推送订阅 关联,registration 表示即将停用的 推送订阅 的 PushSubscription
实例为
oldSubscription,
而 newSubscription 为 null
。
当 推送订阅被停用时,用户代理和推送服务 必须 删除其存储的任何副本。之后针对该推送消息的任何推送订阅 不得再传递。
当关联的service worker 注册被注销时, 该推送订阅 会被停用,尽管推送订阅 可以 更早被停用。
当推送订阅关联的service worker 注册 被清除时,该推送订阅将被删除。
推送服务 指的是一种允许 应用服务器 向 Web 应用程序发送 推送消息 的系统。推送服务为其服务的 推送端点或端点提供服务。
用户代理 会连接到用于创建 推送订阅 的 推送服务。用户代理 可以 限制可用的推送服务的选择。这样做的原因包括与性能相关的考虑,例如服务可用性(包括特定国家或工作场所网络中服务是否被防火墙阻止)、可靠性、电池寿命的影响,以及元数据传递或规避特定推送服务的协议。
推送 API 是一种被称为 “推送” 的强大功能。
为了与 权限 规范集成,本规范定义了
PushPermissionDescriptor
的权限描述符类型。
WebIDLdictionary PushPermissionDescriptor
: PermissionDescriptor {
boolean userVisibleOnly
= false;
};
userVisibleOnly
的语义与
userVisibleOnly
相同。
{name: "push", userVisibleOnly: false}
被认为 强于
{name: "push", userVisibleOnly: true}
。
推送消息的内容是加密的 [RFC8291]。然而,推送服务仍然暴露于由应用服务器通过推送订阅发送给用户代理的消息的元数据。 这包括消息的时间、频率和大小。除了更换推送服务(用户代理可能会禁止此操作),唯一已知的缓解措施是通过填充增加消息的表观大小。
不能保证推送消息是由与Web应用程序具有相同来源的应用服务器发送的。应用服务器可以自行决定与第三方共享使用推送订阅所需的详细信息。
以下要求旨在尽可能保护用户的隐私和安全,并在满足该目标的前提下,保护应用服务器与用户通信的完整性。
用户代理不得在没有用户的明确许可的情况下向Web应用程序提供Push API访问权限。用户代理必须通过用户界面在每次调用subscribe()
方法时获取许可,除非已保存了之前的许可授予,或存在预先安排的信任关系。保留超出当前浏览会话的许可必须是可撤销的。
Push API可能需要唤醒与Service Worker注册关联的Service Worker,以运行开发人员提供的事件处理程序。这可能会导致资源使用,例如网络流量,用户代理应将其归因于创建了推送订阅的Web应用程序。
用户代理可以在获取许可或确定许可状态时考虑PushSubscriptionOptions
。
当许可被撤销时,用户代理可以触发"pushsubscriptionchange
"事件,该事件适用于使用该许可创建的订阅,关联的Service
Worker注册作为registration,代表推送订阅的PushSubscription
实例作为oldSubscription,null
作为newSubscription。用户代理必须并行停用受影响的订阅。
当Service Worker注册被注销时,任何关联的推送订阅必须被停用。
推送端点不得向推送服务之外的其他参与方暴露任何有关用户设备、身份或位置的信息。有关确切要求,请参阅[RFC8030]中的隐私注意事项。
已停用的推送订阅的推送端点不得被重新用于新的推送订阅。这可以防止用户无法移除的持久标识符的创建。它还可以防止利用一个推送订阅的详细信息来向另一个推送订阅发送推送消息。
用户代理必须将Push API的实现仅限于安全上下文中可用。这为用户提供了更好的保护,防止中间人攻击以获取推送订阅数据。浏览器仅可在开发目的下忽略此规则。
本节为非规范性内容。
这一整体框架允许应用服务器响应应用服务器上的事件激活Service Worker。这些事件的信息可以包含在推送消息中,这使得Web应用程序能够适当地响应这些事件,可能无需发起网络请求。
以下代码和图表展示了推送API的一个假设使用示例。
本节为非规范性内容。
// https://example.com/serviceworker.js
this.onpush = event => {
console.log(event.data);
// 从这里我们可以将数据写入IndexedDB,发送到任何打开的窗口,
// 显示通知等。
}
// https://example.com/webapp.js
// 在一个异步函数内部...
try {
const serviceWorkerRegistration = await navigator.serviceWorker.register(
"serviceworker.js"
);
const pushSubscription = await serviceWorkerRegistration.pushManager.subscribe();
// 应用服务器所需的推送订阅详细信息现在已可用,
// 并且可以使用,例如,XMLHttpRequest发送给它。
console.log(pushSubscription.endpoint);
console.log(pushSubscription.getKey("p256dh"));
console.log(pushSubscription.getKey("auth"));
} catch (err) {
// 在生产环境中,可能还需要将错误信息
// 报告回应用服务器。
console.log(error);
}
本节为非规范性内容。
PushSubscription
中包含的字段是应用服务器发送推送消息所需的所有信息。与Push API兼容的推送服务提供符合Web推送协议的推送端点。这些参数和属性包括:
PushSubscription
的URL,允许应用服务器请求将推送消息传递给Web应用程序。
getKey
()
方法用于PushSubscription
中检索用于加密和认证推送消息的密钥材料。
每次调用该函数都会返回一个包含相应密钥值的新的ArrayBuffer
,如果标识的密钥不存在,则返回null
。传递"p256dh
"值可检索与推送订阅关联的椭圆曲线Diffie-Hellman(ECDH)公钥。传递auth
值返回应用服务器用于认证其消息的认证密钥。这些密钥由应用服务器用于加密和认证推送订阅的消息,如[RFC8291]中所述。
Service Worker规范定义了ServiceWorkerRegistration
接口
[SERVICE-WORKERS],而本规范对其进行了扩展。
WebIDL[SecureContext]
partial interface ServiceWorkerRegistration {
readonly attribute PushManager
pushManager
;
};
pushManager
属性暴露了一个PushManager
,它与Service
Worker注册相关联,由暴露该属性的ServiceWorkerRegistration
表示。
PushManager
接口定义了访问推送服务的操作。
WebIDL[Exposed=(Window,Worker), SecureContext]
interface PushManager
{
[SameObject] static readonly attribute FrozenArray<DOMString> supportedContentEncodings
;
Promise<PushSubscription
> subscribe
(optional PushSubscriptionOptionsInit
options = {});
Promise<PushSubscription
?> getSubscription
();
Promise<PermissionState> permissionState
(optional PushSubscriptionOptionsInit
options = {});
};
supportedContentEncodings
属性公开了可用于加密推送消息的有效载荷的支持内容编码的序列。请求推送服务发送推送消息时,使用Content-Encoding
头字段指示内容编码。
用户代理必须支持[RFC8291]中定义的aes128gcm
内容编码,
可以为了兼容性支持早期草案版本中定义的内容编码。
当调用 subscribe()
方法时,必须执行以下步骤:
userVisibleOnly
值设置为 false
且用户代理要求其为 true
,则使用 global 在网络任务源上拒绝 promise 并返回一个 NotAllowedError
DOMException
。
applicationServerKey
的非空值,且推送服务需要提供一个,则使用 global 在网络任务源上拒绝 promise 并返回一个 NotSupportedError
DOMException
。
applicationServerKey
的非空值,执行以下子步骤:
applicationServerKey
是一个 DOMString
,将其值设置为一个包含options
的 applicationServerKey
的 Base64URL 编码的ArrayBuffer
。
InvalidCharacterError
DOMException
并终止这些步骤。
applicationServerKey
描述了 P-256 曲线上的有效点。如果其值无效,使用 global 在网络任务源上拒绝 promise 并返回一个 InvalidAccessError
DOMException
并终止这些步骤。
InvalidStateError
DOMException
并终止这些步骤。
denied
",使用
global 在用户交互任务源上拒绝 promise 并返回一个 NotAllowedError
DOMException
并终止这些步骤。
AbortError
DOMException
并终止这些步骤。
options
属性。BufferSource
的内容按值比较,而不是引用。
InvalidStateError
DOMException
并终止这些步骤。
PushSubscription
。
当调用 getSubscription
方法时,必须执行以下步骤:
AbortError
的DOMException
拒绝
promise 并终止这些步骤。
PushSubscription
解决 promise。
当调用 permissionState()
方法时,必须执行以下步骤:
PermissionDescriptor
,并将其
name
初始化为 "push"。
使用推送服务的权限可以是持久的,即如果存在有效的权限,则不需要为后续订阅重新确认。
如果需要请求权限,则需要通过调用 subscribe
()
方法来执行。
WebIDL[Exposed=(Window,Worker), SecureContext]
interface PushSubscriptionOptions
{
readonly attribute boolean userVisibleOnly
;
[SameObject] readonly attribute ArrayBuffer? applicationServerKey
;
};
userVisibleOnly
属性在获取时,返回其初始化的值。
applicationServerKey
属性在获取时,返回其初始化的值。
如果存在,applicationServerKey
的值必须包含
P-256 椭圆曲线上的一个点 [DSS],并按照 [ANSI-X9-62]
附录A中描述的未压缩形式进行编码(即65个八位字节,以0x04八位字节开头)。当以DOMString
提供时,该值必须使用 base64url 编码 [RFC7515]。
当applicationServerKey
不存在且推送服务因操作原因需要时,用户代理可以拒绝订阅尝试。
applicationServerKey
必须与用于消息加密的值不同 [RFC8291]。
WebIDLdictionary PushSubscriptionOptionsInit
{
boolean userVisibleOnly
= false;
(BufferSource or DOMString)? applicationServerKey
= null;
};
userVisibleOnly
成员,当设置为true
时,表示推送订阅仅用于将效果可见给用户的推送消息,例如通过显示Web通知。[NOTIFICATIONS]
PushSubscriptionOptionsInit
表示与推送订阅相关的附加选项。用户代理 可以在请求用户的明确许可时考虑这些选项。当选项被考虑时,用户代理 应当在接收到的推送消息上强制执行这些选项。
这些选项是可选的,用户代理 可以选择仅支持其中的一部分。用户代理 不得暴露其不支持的选项。
一旦设置,推送订阅 的选项将无法更改。可以通过 unsubscribe
取消现有的 推送订阅,以创建具有新选项的 推送订阅。
applicationServerKey
成员由用户代理用于与推送服务建立推送订阅时使用。applicationServerKey
选项包含应用服务器的椭圆曲线公钥。这是应用服务器在向该推送订阅发送推送消息时用于认证自身的密钥,如 [RFC8292] 中定义;推送服务将拒绝任何没有使用相应私钥生成身份验证令牌的推送消息。
PushSubscription
对象表示一个推送订阅。
WebIDL[Exposed=(Window,Worker), SecureContext]
interface PushSubscription
{
readonly attribute USVString endpoint
;
readonly attribute EpochTimeStamp? expirationTime
;
[SameObject] readonly attribute PushSubscriptionOptions
options
;
ArrayBuffer? getKey
(PushEncryptionKeyName
name);
Promise<boolean> unsubscribe
();
PushSubscriptionJSON
toJSON
();
};
dictionary PushSubscriptionJSON
{
USVString endpoint
;
EpochTimeStamp? expirationTime
= null;
record<DOMString, USVString> keys
;
};
当获取endpoint
属性时,用户代理必须返回与推送订阅相关联的推送端点。用户代理必须使用不包含依赖于输入的分支的序列化方法(即,恒定时间的方法)。
当获取expirationTime
属性时,用户代理必须返回与推送订阅相关联的订阅过期时间,如果没有则返回null
。
当获取options
属性时,
用户代理必须返回一个表示与推送订阅关联的选项的PushSubscriptionOptions
对象。
getKey()
方法用于检索可用于加密和验证消息的密钥材料。
当调用getKey
()
时,执行以下过程:
name
参数指定的密钥对应的内部槽位。
null
。
ArrayBuffer
实例。
p256dh
"公钥使用定义在
[ANSI-X9-62]
附录A中的未压缩格式(即65个字节序列,以0x04字节开头)编码。
auth
参数包含用于
用户代理
验证由应用服务器发送的消息的字节序列。
p256dh
和auth
两个密钥名称必须被支持,其值必须与用户代理在接收推送消息时解密所需的值相对应,按照[RFC8291]的规定。
当调用unsubscribe()
方法时,必须运行以下步骤:
false
解析promise并终止这些步骤。true
解析promise。
当调用toJSON()
方法时,必须运行以下步骤:
PushSubscriptionJSON
字典。
endpoint
属性的结果。
expirationTime
属性的结果。
record<DOMString, USVString>
的新空实例。
一个PushSubscriptionJSON
字典代表了JSON类型的PushSubscription
。在ECMAScript中,这可以通过JSON
.stringify
()
函数转换为JSON字符串。
keys
记录包含每个支持的PushEncryptionKeyName
条目的URL安全base64编码表示[RFC4648]。
请注意,PushSubscription
的选项不会被序列化。
用于推送消息加密的加密密钥通过
getKey
()
方法或
PushSubscription
的序列化器提供给Web应用程序。
每个密钥使用PushEncryptionKeyName
枚举中的一个值命名。
WebIDLenum PushEncryptionKeyName
{
"p256dh
",
"auth
"
};
p256dh
值用于检索P-256 ECDH Diffie-Hellman 公钥,
如[RFC8291] 中所描述。
auth
值用于检索身份验证密钥,
如[RFC8291] 中所描述。
WebIDL[Exposed=ServiceWorker, SecureContext]
interface PushMessageData
{
ArrayBuffer arrayBuffer
();
Blob blob
();
Uint8Array bytes
();
any json
();
USVString text
();
};
PushMessageData
对象关联了一个 字节序列(一个 字节序列),
这是在创建时设置的。
arrayBuffer()
方法步骤是返回一个 ArrayBuffer
,其内容为
this 的
字节序列。在创建
ArrayBuffer
对象时抛出的异常将被重新抛出。
blob()
方法步骤是返回一个新的 Blob
对象,其内容为
this 的
字节序列。
bytes()
方法步骤是返回一个新的 Uint8Array
,其背后的
ArrayBuffer
的内容为
this 的
字节序列。在创建
ArrayBuffer
对象时抛出的异常将被重新抛出。
json()
方法步骤是返回
将字节序列解析为JavaScript值的结果,给定
this 的
字节序列。
text()
方法步骤是返回运行 UTF-8 解码的结果,
给定 this
的 字节序列。
要从object中提取字节序列,请运行以下步骤:
BufferSource
USVString
Service Worker 规范定义了一个 ServiceWorkerGlobalScope
接口 [SERVICE-WORKERS],该规范对此进行了扩展。
WebIDL[Exposed=ServiceWorker, SecureContext]
partial interface ServiceWorkerGlobalScope {
attribute EventHandler onpush
;
attribute EventHandler onpushsubscriptionchange
;
};
onpush
属性是一个
事件处理器 IDL 属性,其对应的
事件处理器事件类型为 "push
"。 "push
" 事件表示
已接收到一个 推送消息,用于某个
推送订阅。
onpushsubscriptionchange
属性是一个
事件处理器 IDL 属性,其对应的
事件处理器事件类型为 "pushsubscriptionchange
"。
WebIDL[Exposed=ServiceWorker, SecureContext]
interface PushEvent
: ExtendableEvent {
constructor
(DOMString type, optional PushEventInit
eventInitDict = {});
readonly attribute PushMessageData
? data
;
};
当 constructor
的 PushEvent
接口或继承自 PushEvent
接口的接口被调用时,通常的 事件构造步骤 会扩展为包括以下步骤:
data
成员不存在,将事件的 data
属性设置为 null
并终止这些步骤。
data
" 成员中 提取字节序列 的结果。
data
属性设置为一个新的 PushMessageData
实例,并将
bytes
设置为 b。
当获取 data
时,返回其初始化的值。
WebIDLtypedef (BufferSource or USVString) PushMessageDataInit
;
dictionary PushEventInit
: ExtendableEventInit {
PushMessageDataInit
data
;
};
data
成员包含了在 推送消息 中包含的数据,并且在 用户代理 验证其真实性时会被设置。 在所有其他情况下,该值将被设置为 null
。
当 用户代理 从 推送服务 接收到 推送消息 时, 必须 执行以下步骤。
触发名为
push
的功能事件,并在 registration 上使用 PushEvent
,具有以下属性:
data
PushMessageData
对象,其 字节 为 bytes。
然后并行运行以下步骤,并使用 dispatchedEvent:
pushsubscriptionchange 事件表示 推送订阅 的变更,这些变更是在应用程序控制之外触发的,例如由于订阅已刷新、撤销或丢失。
要在给定 registration 的 service worker
注册、newSubscription 和 oldSubscription 的情况下
触发 "pushsubscriptionchange
" 事件,用户代理 必须触发一个功能事件,
名为 "pushsubscriptionchange
",使用
PushSubscriptionChangeEvent
在
registration 上,
并具有以下属性:
newSubscription
oldSubscription
当将新的 推送订阅 详细信息发送到 应用服务器 时, 可以考虑使用更可靠的同步机制,例如 [WEB-BACKGROUND-SYNC]。用户可能处于不可靠的网络条件下,导致请求失败。
WebIDL[Exposed=ServiceWorker, SecureContext]
interface PushSubscriptionChangeEvent
: ExtendableEvent {
constructor
(DOMString type, optional PushSubscriptionChangeEventInit
eventInitDict = {});
readonly attribute PushSubscription
? newSubscription
;
readonly attribute PushSubscription
? oldSubscription
;
};
当获取 newSubscription
属性时,返回其初始化的值。
当获取 oldSubscription
属性时,返回其初始化的值。
WebIDLdictionary PushSubscriptionChangeEventInit
: ExtendableEventInit {
PushSubscription
newSubscription
= null;
PushSubscription
oldSubscription
= null;
};
newSubscription
成员详细说明了在调用
pushsubscriptionchange 事件时有效的
推送订阅。 当未能建立新的
推送订阅 时,
该值将为 null
,例如因为 web 应用程序失去了明确许可。
oldSubscription
成员详细说明了不应再使用的
推送订阅。 当 用户代理 无法提供完整详细信息时,
例如由于部分数据库损坏,该值将为 null
。
推送 API 本身不提供任何呈现从 推送服务 接收到的数据的手段。相反,推送 API 依赖其他 API—— 主要是 通知 API 标准 ——将接收到的信息呈现给最终用户。 因此,推送 API 本身没有无障碍要求。然而,诸如 [通知] 等规范提供了关于如何以无障碍方式呈现通知的指导。
此外,呈现无障碍界面可能需要传输比推送消息所能传达的更多信息。推送消息最适合传递少量内容或标识符。任何更大的资源都需要从服务器获取。
与标记为非规范性的部分一样,本规范中的所有作者指南、图表、示例和注释均为非规范性内容。本规范中的其他内容均为规范性内容。
本文档中的关键字 可以、必须、不得、应 和 不应 应按照 BCP 14 中的描述进行解释, 当且仅当这些词汇以大写形式出现时,如此处所示。 [RFC2119] [RFC8174]
本规范定义了一致性标准,适用于一个单一产品:实现其所包含接口的 用户代理。
WebIDLdictionary PushPermissionDescriptor
: PermissionDescriptor {
boolean userVisibleOnly
= false;
};
[SecureContext]
partial interface ServiceWorkerRegistration {
readonly attribute PushManager
pushManager
;
};
[Exposed=(Window,Worker), SecureContext]
interface PushManager
{
[SameObject] static readonly attribute FrozenArray<DOMString> supportedContentEncodings
;
Promise<PushSubscription
> subscribe
(optional PushSubscriptionOptionsInit
options = {});
Promise<PushSubscription
?> getSubscription
();
Promise<PermissionState> permissionState
(optional PushSubscriptionOptionsInit
options = {});
};
[Exposed=(Window,Worker), SecureContext]
interface PushSubscriptionOptions
{
readonly attribute boolean userVisibleOnly
;
[SameObject] readonly attribute ArrayBuffer? applicationServerKey
;
};
dictionary PushSubscriptionOptionsInit
{
boolean userVisibleOnly
= false;
(BufferSource or DOMString)? applicationServerKey
= null;
};
[Exposed=(Window,Worker), SecureContext]
interface PushSubscription
{
readonly attribute USVString endpoint
;
readonly attribute EpochTimeStamp? expirationTime
;
[SameObject] readonly attribute PushSubscriptionOptions
options
;
ArrayBuffer? getKey
(PushEncryptionKeyName
name);
Promise<boolean> unsubscribe
();
PushSubscriptionJSON
toJSON
();
};
dictionary PushSubscriptionJSON
{
USVString endpoint
;
EpochTimeStamp? expirationTime
= null;
record<DOMString, USVString> keys
;
};
enum PushEncryptionKeyName
{
"p256dh
",
"auth
"
};
[Exposed=ServiceWorker, SecureContext]
interface PushMessageData
{
ArrayBuffer arrayBuffer
();
Blob blob
();
Uint8Array bytes
();
any json
();
USVString text
();
};
[Exposed=ServiceWorker, SecureContext]
partial interface ServiceWorkerGlobalScope {
attribute EventHandler onpush
;
attribute EventHandler onpushsubscriptionchange
;
};
[Exposed=ServiceWorker, SecureContext]
interface PushEvent
: ExtendableEvent {
constructor
(DOMString type, optional PushEventInit
eventInitDict = {});
readonly attribute PushMessageData
? data
;
};
typedef (BufferSource or USVString) PushMessageDataInit
;
dictionary PushEventInit
: ExtendableEventInit {
PushMessageDataInit
data
;
};
[Exposed=ServiceWorker, SecureContext]
interface PushSubscriptionChangeEvent
: ExtendableEvent {
constructor
(DOMString type, optional PushSubscriptionChangeEventInit
eventInitDict = {});
readonly attribute PushSubscription
? newSubscription
;
readonly attribute PushSubscription
? oldSubscription
;
};
dictionary PushSubscriptionChangeEventInit
: ExtendableEventInit {
PushSubscription
newSubscription
= null;
PushSubscription
oldSubscription
= null;
};
编辑们要感谢实施 Firefox OS 推送消息解决方案的 Mozilla 和 Telefónica Digital 团队,以及以下为本文档提供了重要技术意见的人:Antonio Amaya、Miguel García Arribas、Ben Bangert、Kit Cambridge、José Manuel Cantera、JR Conlin、Albert Crespell、Matt Gaunt、Phil Jenvey、Guillermo López、Nikhil Marathe、John Mellor、Pınar Özlen、Fernando R. Sela、Shijun Sun 和 Doug Turner。
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: