Abstract

The Push API provides webapps with scripted access to server-sent messages, for simplicity referred to here as push messages, as delivered by push services. A push service allows a webapp server to send messages to a webapp, regardless of whether the webapp is currently active on the user agent. The push message will be delivered to a Service Worker, which could then store the message's data or display a notification to the user.

This specification is designed to promote compatibility with any delivery method for push messages from push services to user agents.

Status of This Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

This document was published by the Web Applications Working Group as a Working Draft. This document is intended to become a W3C Recommendation. If you wish to make comments regarding this document, please send them to public-webapps@w3.org (subscribe, archives) with [Push API] at the start of your email's subject. All comments are welcome.

Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

This document is governed by the 14 October 2005 W3C Process Document.

Table of Contents

1. Introduction

This section is non-normative.

As defined here, push services support delivery of webapp server messages in the following contexts and related use cases:

2. Conformance

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

The key words MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL in this specification are to be interpreted as described in [RFC2119].

This specification defines conformance criteria that apply to a single product: the user agent that implements the interfaces that it contains.

Implementations that use ECMAScript to implement the APIs defined in this specification MUST implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification [WEBIDL].

3. Terminology

The terms event handler, event handler event type, queue a task, and fire a simple event are defined in [HTML5].

Promise is defined in [ECMASCRIPT].

EventInit, DOMException, AbortError, NotFoundError, and SecurityError are defined in [DOM].

Service Worker, ServiceWorkerRegistration, ServiceWorkerGlobalScope, and ExtendableEvent are defined in [SERVICE-WORKERS].

The term webapp refers to a Web application, i.e. an application implemented using Web technologies, and executing within the context of a Web user agent, e.g. a Web browser or other Web runtime environment.

The term webapp server refers to server-side components of a webapp.

The term push message refers to an indication to a webapp that there is new information for it from the webapp server, all or part of which MAY be contained in the push message itself.

The term push registration refers to each logical channel aimed at delivering push messages from an webapp server to a webapp, which is created by a distinct registration of such webapp via this Push API.

The term push service refers to an overall end-to-end system that allows webapp servers to send push messages to a webapp.

The term push server refers to the push service access point via which webapp-servers can initiate push message delivery. Push servers typically expose APIs specific to the push service, e.g. for push message delivery initiation.

The term express permission refers to an act by the user, e.g. via user interface or host device platform features, via which the user approves the permission of a webapp to access the Push API.

4. Security and privacy considerations

User agents MUST NOT provide Push API access to webapps without the express permission of the user. User agents MUST acquire consent for permission through a user interface for each call to the register() method, unless a prearranged trust relationship applies.

User agents MAY support prearranged trust relationships that do not require such per-request user interfaces.

User agents MUST implement the Push API to be HTTPS-only. SSL-only support provides better protection for the user against man-in-the-middle attacks intended to obtain push registration data. Browsers may ignore this rule for development purposes only.

Permissions that are preserved beyond the current browsing session MUST be revocable.

5. Push Framework

This section is non-normative.

Although push services are expected to differ in deployment, a typical deployment is expected to have the following general entities and example operation for delivery of push messages:

This overall framework allows webapp servers to inform webapps that new data is available at the webapp server, or pass the new data directly to the webapp in the push message.

The push API enables delivery of arbitrary application data to webapps, and makes no assumptions about the over-the-air/wire protocol used by push services. As such, the details of what types of data flow through a push services for a particular webapp are specific to the push service and webapp. As needed, clarification about what data flows over-the-air/wire should be sought from push service operators or webapp developers.

The following code and diagram illustrate a hypothetical use of the push API.

5.1 Example

This section is non-normative.

Example 1
// https://example.com/serviceworker.js
this.onpush = function(event) {
  console.log(event.data);
  // From here we can write the data to IndexedDB, send it to any open windows,
  // display a notification, etc.
}

// https://example.com/webapp.js
navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
  serviceWorkerRegistration.pushRegistrationManager.register().then(
    function(pushRegistration) {
      console.log(pushRegistration.registrationId);
      console.log(pushRegistration.endpoint);
      // The push registration details needed by the application server to push
      // messages to the push service are now available, and can be sent to the
      // application server using, for example, an XMLHttpRequest.
    }, function(error) {
      // During development it often helps to log errors to the console. In a
      // production environment it might make sense to also report information
      // about errors back to the application server.
      console.log(error);
    }
  });
});

5.2 Sequence diagram

This section is non-normative.

Example flow of events for registration, message delivery, and unregistration
Fig. 1 Example flow of events for registration, message delivery, and unregistration

5.3 Push Server Discovery and API Use

This specification does not define either specific normative methods via which webapps can determine the applicable push system, or initiate push requests through that system via a push server API. While these limitations add complexity for webapp developers, they reflect the current reality of a diversity of push systems, for which convergence at least in push server APIs, is not expected to be a short-term possibility. While a converged push server API is a worthwhile goal and may be addressed in a different specification, the Push API defined here has been designed to enable the current variety of push systems to be used as appropriate for the webapp host device or software platform. This section provides examples of how a webapp can be designed to work with a variety of hypothetical push systems as needed.

The Push API provides several interface parameters and attributes that can enable a webapp to deliver and obtain the necessary push system specific data enabling use of that particular push system. These parameters and attributes include:

Push systems that are compatible with the Push API will be expected to clarify how these data are used in the push server APIs of the specific system, e.g. through their developer programs. Examples of considerations include:

The Push API does not provide any pushRegistration attributes that normatively identify the particular push system that applies to the registration. Webapps that are designed to work with a single push system are assumed to know inherently how to use the push server API of that system. For such webapps, a key consideration is ensuring that if the webapp is used on a device or browser that does not support the necessary push system, that either the user is informed that the push-dependent webapp functions will not work, or the webapp must use alternate methods e.g. [websockets] or [SSE] to deliver the server-initiated data.

Prior to use of a push server API, webapp servers that are designed to work with multiple push systems may need to determine the applicable system by parsing the endpoint to detect the push system from the URI domain.

6. Extensions to the ServiceWorkerRegistration interface

The Service Worker specification defines a ServiceWorkerRegistration interface [SERVICE-WORKERS], which this specification extends.

partial interface ServiceWorkerRegistration {
    readonly    attribute PushRegistrationManager pushRegistrationManager;
};

The pushRegistrationManager attribute exposes the PushRegistrationManager for the Service Worker identified by the ServiceWorkerRegistration.

7. PushRegistrationManager interface

The PushRegistrationManager interface defines the operations that enable webapps to establish access to push services. Note that just a single push registration is allowed per webapp.

interface PushRegistrationManager {
    Promise<PushRegistration>     register ();
    Promise<PushRegistration>     unregister ();
    Promise<PushRegistration>     getRegistration ();
    Promise<PushPermissionStatus> hasPermission ();
};

The register method when invoked MUST run the following steps:

  1. Let promise be a new Promise.
  2. Return promise and continue the following steps asynchronously.
  3. If the scheme of the document url is not https, reject promise with a DOMException whose name is "SecurityError" and terminate these steps.
  4. Ask the user whether they allow the webapp to receive push messages, unless a prearranged trust relationship applies or the user has already granted or denied permission explicitly for this webapp.
  5. If not granted, reject promise with a DOMException whose name is "PermissionDeniedError" and terminate these steps.
  6. If the webapp is already registered, run the following substeps:
    1. Retrieve the push registration associated with the webapp.
    2. If there is an error, reject promise with a DOMException whose name is "AbortError" and terminate these steps.
    3. When the request has been completed, resolve promise with a PushRegistration providing the details of the retrieved push registration.
  7. Make a request to the system to create a new push registration for the webapp.
  8. If there is an error, reject promise with a DOMException whose name is "AbortError" and terminate these steps.
  9. When the request has been completed, resolve promise with a PushRegistration providing the details of the new push registration.
Note

PermissionDeniedError has not yet been defined in a specification, this document currently links to the bug for defining it.

The unregister method when invoked MUST run the following steps:

  1. Let promise be a new Promise.
  2. Return promise and continue the following steps asynchronously.
  3. If the webapp is not registered, reject promise with a DOMException whose name is "NotFoundError" and terminate these steps.
  4. Make a request to the system to deactivate the push registration associated with the webapp.
  5. If there is an error, reject promise with a DOMException whose name is "AbortError" and terminate these steps.
  6. When the request has been completed, resolve promise with a PushRegistration providing the details of the push registration which has been unregistered.

The getRegistration method when invoked MUST run the following steps:

  1. Let promise be a new Promise.
  2. Return promise and continue the following steps asynchronously.
  3. If the webapp is not registered, reject promise with a DOMException whose name is "NotFoundError" and terminate these steps.
  4. Retrieve the push registration associated with the webapp.
  5. If there is an error, reject promise with a DOMException whose name is "AbortError" and terminate these steps.
  6. When the request has been completed, resolve promise with a PushRegistration providing the details of the retrieved push registration.

The hasPermission method when invoked MUST run the following steps:

  1. Let promise be a new Promise.
  2. Return promise and continue the following steps asynchronously.
  3. Retrieve the push permission status (PushPermissionStatus) of the requesting webapp
  4. If there is an error, reject promise with no arguments and terminate these steps.
  5. When the request has been completed, resolve promise with PushPermissionStatus providing the push permission status.

Permission to use the push service can be persistent, that is, it does not need to be reconfirmed for subsequent registrations if a valid permission exists.

If there is a need to ask for permission, it needs to be done by invoking the register method.

7.1 Push Registration Persistence

To facilitate persistence of push registrations when a webapp is closed, it can use a Service Worker to register for and receive push events. In that case, even if the webapp parent window is closed, the pushRegistration object will still enable delivery of push messages, through the Service Worker. The push messages, can then be processed by the Service Worker, e.g. including one or more of the following actions:

If a webapp creates a push registration without using a Service Worker, the pushRegistration object will persist only as long as the webapp window is open.

7.2 Push Registration Uniqueness

Each push registration is unique, i.e. a single instance specific to each webapp and call to the register interface.

webapps that create multiple push registrations are responsible for mapping the individual registrations to specific app functions as necessary. For example, the webapp or webapp server can associate a specific pushRegistration to a particular function of the app through JavaScript.

8. PushRegistration interface

The PushRegistration interface contains information about a specific channel used by a webapp to receive push messages.

interface PushRegistration {
    readonly    attribute DOMString endpoint;
    readonly    attribute DOMString registrationId;
};

When getting the endpoint attribute, the user agent MUST return the absolute URL exposed by the push server where the webapp server can send push messages to this webapp. The value of endpoint may be the same for multiple webapps / webapp instances running on multiple devices.

When getting the registrationId attribute, the user agent MUST return a univocal identifier of this push registration in the push server. It is used by the webapp server to indicate the target of the push messages that it submits to the push server. Each pair of registrationId and endpoint is expected to be unique and specific to a particular webapp instance running on a specific device.

9. Events

The Service Worker specification defines a ServiceWorkerGlobalScope interface [SERVICE-WORKERS], which this specification extends.

partial interface ServiceWorkerGlobalScope {
                attribute EventHandler onpush;
                attribute EventHandler onpushregistrationlost;
};

The onpush attribute is an event handler whose corresponding event handler event type is push.

The onpushregistrationlost attribute is an event handler whose corresponding event handler event type is pushregistrationlost.

9.1 The push event

The PushEvent interface represents a received push message.

dictionary PushEventInit : EventInit {
    DOMString? data;
};

[Constructor(DOMString type, optional PushEventInit eventInitDict), Exposed=ServiceWorker] interface PushEvent : ExtendableEvent { readonly attribute DOMString? data; };

When getting the data attribute of a PushEventInit object, the user agent MUST return the message data received by the user agent in the push message, or null if no data was received.

When getting the data attribute of a PushEvent, the user agent MUST return the message data received by the user agent in the push message, or null if no data was received.

Upon receiving a push message for a webapp from the push service the user agent MUST run the following steps:

  1. If the Service Worker associated with the webapp is not running, start it.
  2. Let scope be the ServiceWorkerGlobalScope of the Service Worker associated with the webapp.
  3. Let event be a new PushEvent whose data attribute is the message data received by the user agent in the push message, or null if no data was received.
  4. Queue a task to fire event as a simple event named push at scope.

9.2 The pushregistrationlost event

Upon any event that makes a push registration no longer valid, e.g. push server database failure, the user agent MUST run the following steps:

  1. If the Service Worker associated with the webapp is not running, start it.
  2. Let scope be the ServiceWorkerGlobalScope of the Service Worker associated with the webapp.
  3. Queue a task to fire a simple event named pushregistrationlost at scope.

10. Enumerations

enum PushPermissionStatus {
    "granted",
    "denied",
    "default"
};
Enumeration description
granted The webapp has permission to use Push API.
denied The webapp has been denied permission to use Push API.
default The webapp needs to ask for permission in order to use Push API.

A. Acknowledgements

The editors would like to express their gratitude to the Mozilla and Telefónica Digital teams implementing the Firefox OS Push message solution and specially to Doug Turner, Nikhil Marathe, Fernando R. Sela, Guillermo López, Antonio Amaya, José Manuel Cantera and Albert Crespell, for their technical guidance, implementation work and support.

B. References

B.1 Normative references

[DOM]
Anne van Kesteren; Aryeh Gregor; Ms2ger; Alex Russell; Robin Berjon. W3C DOM4. 10 July 2014. W3C Last Call Working Draft. URL: http://www.w3.org/TR/dom/
[ECMASCRIPT]
Allen Wirfs-Brock. ECMA-262 ECMAScript Language Specification, Edition 6. Draft. URL: http://people.mozilla.org/~jorendorff/es6-draft.html
[HTML5]
Robin Berjon; Steve Faulkner; Travis Leithead; Erika Doyle Navara; Edward O'Connor; Silvia Pfeiffer. HTML5. 16 September 2014. W3C Proposed Recommendation. URL: http://www.w3.org/TR/html5/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: http://www.ietf.org/rfc/rfc2119.txt
[SERVICE-WORKERS]
Alex Russell; Jungkee Song. Service Workers. 8 May 2014. W3C Working Draft. URL: http://www.w3.org/TR/service-workers/
[WEBIDL]
Cameron McCormack. Web IDL. 19 April 2012. W3C Candidate Recommendation. URL: http://www.w3.org/TR/WebIDL/

B.2 Informative references

[SSE]
Ian Hickson. Server-Sent Events. 11 December 2012. W3C Candidate Recommendation. URL: http://www.w3.org/TR/eventsource/
[webmessaging]
Ian Hickson. HTML5 Web Messaging. 1 May 2012. W3C Candidate Recommendation. URL: http://www.w3.org/TR/webmessaging/
[websockets]
Ian Hickson. The WebSocket API. 20 September 2012. W3C Candidate Recommendation. URL: http://www.w3.org/TR/websockets/