Service Workers 1

W3C Candidate Recommendation,

This version:
https://www.w3.org/TR/2019/CR-service-workers-1-20191119/
Latest published version:
https://www.w3.org/TR/service-workers-1/
Editor's Draft:
https://w3c.github.io/ServiceWorker/v1/
Previous Versions:
Issue Tracking:
GitHub
Editors:
(Google)
(Microsoft‚ represented Samsung until April 2018)
(Google)
(Google)
Implementation report:
https://www.w3.org/sw/v1/implementation-report
Tests:
web-platform-tests service-workers/ (ongoing work)
V1 Branch

This spec is a subset of the nightly version. It is advancing toward a W3C Recommendation. For implementers and developers who seek all the latest features, Service Workers Nightly is the right document as it constantly reflects new requirements.


Abstract

This specification describes a method that enables applications to take advantage of persistent background processing, including hooks to enable bootstrapping of web applications while offline.

The core of this system is an event-driven Web Worker, which responds to events dispatched from documents and other sources. A system for managing installation, versions, and upgrades is provided.

The service worker is a generic entry point for event-driven background processing in the Web Platform that is extensible by other specifications.

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 https://www.w3.org/TR/.

This document was published by the Service Workers Working Group as a Candidate Recommendation. This document is intended to become a W3C Recommendation. This document will remain a Candidate Recommendation at least until in order to ensure the opportunity for wide review.

An implementation report will be available. Per charter, this specification is expected to have at least two independent implementations of each feature defined.

Feedback and comments on this specification are welcome, please send them to [email protected] (subscribe, archives) with [service-workers] at the start of your email’s subject.

Publication as a Candidate Recommendation 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 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 1 March 2019 W3C Process Document.

1. Motivations

This section is non-normative.

Web Applications traditionally assume that the network is reachable. This assumption pervades the platform. HTML documents are loaded over HTTP and traditionally fetch all of their sub-resources via subsequent HTTP requests. This places web content at a disadvantage versus other technology stacks.

The service worker is designed first to redress this balance by providing a Web Worker context, which can be started by a runtime when navigations are about to occur. This event-driven worker is registered against an origin and a path (or pattern), meaning it can be consulted when navigations occur to that location. Events that correspond to network requests are dispatched to the worker and the responses generated by the worker may override default network stack behavior. This puts the service worker, conceptually, between the network and a document renderer, allowing the service worker to provide content for documents, even while offline.

Web developers familiar with previous attempts to solve the offline problem have reported a deficit of flexibility in those solutions. As a result, the service worker is highly procedural, providing a maximum of flexibility at the price of additional complexity for developers. Part of this complexity arises from the need to keep service workers responsive in the face of a single-threaded execution model. As a result, APIs exposed by service workers are almost entirely asynchronous, a pattern familiar in other JavaScript contexts but accentuated here by the need to avoid blocking document and resource loading.

Developers using the HTML5 Application Cache have also reported that several attributes of the design contribute to unrecoverable errors. A key design principle of the service worker is that errors should always be recoverable. Many details of the update process of service workers are designed to avoid these hazards.

Service workers are started and kept alive by their relationship to events, not documents. This design borrows heavily from developer and vendor experience with Shared Workers and Chrome Background Pages. A key lesson from these systems is the necessity to time-limit the execution of background processing contexts, both to conserve resources and to ensure that background context loss and restart is top-of-mind for developers. As a result, service workers bear more than a passing resemblance to Chrome Event Pages, the successor to Background Pages. Service workers may be started by user agents without an attached document and may be killed by the user agent at nearly any time. Conceptually, service workers can be thought of as Shared Workers that can start, process events, and die without ever handling messages from documents. Developers are advised to keep in mind that service workers may be started and killed many times a second.

Service workers are generic, event-driven, time-limited script contexts that run at an origin. These properties make them natural endpoints for a range of runtime services that may outlive the context of a particular document, e.g. handling push notifications, background data synchronization, responding to resource requests from other origins, or receiving centralized updates to expensive-to-calculate data (e.g., geolocation or gyroscope).

2. Model

2.1. Service Worker

A service worker is a type of web worker. A service worker executes in the registering service worker client's origin.

A service worker has an associated state, which is one of "parsed", "installing", "installed", "activating", "activated", and "redundant". It is initially "parsed".

A service worker has an associated script url (a URL).

A service worker has an associated type which is either "classic" or "module". Unless stated otherwise, it is "classic".

A service worker has an associated containing service worker registration (a service worker registration), which contains itself.

A service worker has an associated global object (a ServiceWorkerGlobalScope object or null).

A service worker has an associated script resource (a script), which represents its own script resource. It is initially set to null.

A script resource has an associated has ever been evaluated flag. It is initially unset.

A script resource has an associated HTTPS state (an HTTPS state value). It is initially "none".

A script resource has an associated referrer policy (a referrer policy). It is initially the empty string.

A service worker has an associated script resource map which is an ordered map where the keys are URLs and the values are responses.

A service worker has an associated skip waiting flag. Unless stated otherwise it is unset.

A service worker has an associated classic scripts imported flag. It is initially unset.

A service worker has an associated set of event types to handle (a set) whose item is an event listener’s event type. It is initially an empty set.

A service worker has an associated set of extended events (a set) whose item is an ExtendableEvent. It is initially an empty set.

2.1.1. Lifetime

The lifetime of a service worker is tied to the execution lifetime of events and not references held by service worker clients to the ServiceWorker object.

A user agent may terminate service workers at any time it:

  • Has no event to handle.

  • Detects abnormal operation: such as infinite loops and tasks exceeding imposed time limits (if any) while handling the events.

A service worker has an associated start status which can be null or a Completion. It is initially null.

A service worker is said to be running if its event loop is running.

2.1.2. Events

The Service Workers specification defines service worker events (each of which is an event) that include (see the list):

2.2. Service Worker Registration

A service worker registration is a tuple of a scope url and a set of service workers, an installing worker, a waiting worker, and an active worker. A user agent may enable many service worker registrations at a single origin so long as the scope url of the service worker registration differs. A service worker registration of an identical scope url when one already exists in the user agent causes the existing service worker registration to be replaced.

A service worker registration has an associated scope url (a URL).

A service worker registration has an associated installing worker (a service worker or null) whose state is "installing". It is initially set to null.

A service worker registration has an associated waiting worker (a service worker or null) whose state is "installed". It is initially set to null.

A service worker registration has an associated active worker (a service worker or null) whose state is either "activating" or "activated". It is initially set to null.

A service worker registration has an associated last update check time. It is initially set to null.

A service worker registration is said to be stale if the registration’s last update check time is non-null and the time difference in seconds calculated by the current time minus the registration’s last update check time is greater than 86400.

A service worker registration has an associated update via cache mode, which is "imports", "all", or "none". It is initially set to "imports".

A service worker registration has one or more task queues that back up the tasks from its active worker’s event loop’s corresponding task queues. (The target task sources for this back up operation are the handle fetch task source and the handle functional event task source.) The user agent dumps the active worker’s tasks to the service worker registration's task queues when the active worker is terminated and re-queues those tasks to the active worker’s event loop’s corresponding task queues when the active worker spins off. Unlike the task queues owned by event loops, the service worker registration's task queues are not processed by any event loops in and of itself.

A service worker registration is said to be unregistered if scope to registration map[this service worker registration's scope url] is not this service worker registration.

2.2.1. Lifetime

A user agent must persistently keep a list of registered service worker registrations unless otherwise they are explicitly unregistered. A user agent has a scope to registration map that stores the entries of the tuple of service worker registration's scope url, serialized, and the corresponding service worker registration. The lifetime of service worker registrations is beyond that of the ServiceWorkerRegistration objects which represent them within the lifetime of their corresponding service worker clients.

2.3. Service Worker Client

A service worker client is an environment.

A service worker client has an associated discarded flag. It is initially unset.

Each service worker client has the following environment discarding steps:

  1. Set client’s discarded flag.

Note: Implementations can discard clients whose discarded flag is set.

A service worker client has an algorithm defined as the origin that returns the service worker client's origin if the service worker client is an environment settings object, and the service worker client's creation URL’s origin otherwise.

A window client is a service worker client whose global object is a Window object.

A dedicated worker client is a service worker client whose global object is a DedicatedWorkerGlobalScope object.

A shared worker client is a service worker client whose global object is a SharedWorkerGlobalScope object.

A worker client is either a dedicated worker client or a shared worker client.

2.4. Control and Use

A service worker client has an active service worker that serves its own loading and its subresources. When a service worker client has a non-null active service worker, it is said to be controlled by that active service worker. When a service worker client is controlled by a service worker, it is said that the service worker client is using the service worker’s containing service worker registration. A service worker client's active service worker is determined as explained in the following subsections.

The rest of the section is non-normative.

Note: The behavior in this section is not fully specified yet and will be specified in HTML Standard. The work is tracked by the issue and the pull request. For any Service Workers changes, we will incorporate them into Service Workers Nightly.

2.4.1. The window client case

A window client is created when a browsing context is created and when it navigates.

When a window client is created in the process of a browsing context creation:

If the browsing context's initial active document's origin is an opaque origin, the window client's active service worker is set to null. Otherwise, it is set to the creator document's service worker client's active service worker.

When a window client is created in the process of the browsing context's navigation:

If the fetch is routed through HTTP fetch, the window client's active service worker is set to the result of the service worker registration matching. Otherwise, if the created document's origin is an opaque origin or not the same as its creator document's origin, the window client's active service worker is set to null. Otherwise, it is set to the creator document's service worker client's active service worker.

Note: For an initial navigation with replacement enabled, the initial window client that was created when the browsing context was created is reused, but the active service worker is determined by the same behavior as above.

Note: Sandboxed iframes without the sandboxing directives, allow-same-origin and allow-scripts, result in having the active service worker value of null as their origin is an opaque origin.

2.4.2. The worker client case

A worker client is created when the user agent runs a worker.

When the worker client is created:

When the fetch is routed through HTTP fetch, the worker client's active service worker is set to the result of the service worker registration matching. Otherwise, if the worker client's origin is an opaque origin, or the request's URL is a blob URL and the worker client's origin is not the same as the origin of the last item in the worker client's global object's owner set, the worker client's active service worker is set to null. Otherwise, it is set to the active service worker of the environment settings object of the last item in the worker client's global object's owner set.

Note: Window clients and worker clients with a data: URL result in having the active service worker value of null as their origin is an opaque origin. Window clients and worker clients with a blob URL can inherit the active service worker of their creator document or owner, but if the request's origin is not the same as the origin of their creator document or owner, the active service worker is set to null.

2.5. Task Sources

The following additional task sources are used by service workers.

The handle fetch task source

This task source is used for dispatching fetch events to service workers.

The handle functional event task source

This task source is used for features that dispatch other functional events, e.g. push events, to service workers.

Note: A user agent may use a separate task source for each functional event type in order to avoid a head-of-line blocking phenomenon for certain functional events.

2.6. User Agent Shutdown

A user agent must maintain the state of its stored service worker registrations across restarts with the following rules:

To attain this, the user agent must invoke Handle User Agent Shutdown when it terminates.

3. Client Context

Bootstrapping with a service worker:
// scope defaults to the path the script sits in
// "/" in this example
navigator.serviceWorker.register("/serviceworker.js").then(registration => {
  console.log("success!");
  if (registration.installing) {
    registration.installing.postMessage("Howdy from your installing page.");
  }
}, err => {
  console.error("Installing the worker failed!", err);
});

3.1. ServiceWorker

[SecureContext, Exposed=(Window,Worker)]
interface ServiceWorker : EventTarget {
  readonly attribute USVString scriptURL;
  readonly attribute ServiceWorkerState state;
  void postMessage(any message, optional sequence<object> transfer = []);

  // event
  attribute EventHandler onstatechange;
};
ServiceWorker includes AbstractWorker;

enum ServiceWorkerState {
  "installing",
  "installed",
  "activating",
  "activated",
  "redundant"
};

A ServiceWorker object represents a service worker. Each ServiceWorker object is associated with a service worker. Multiple separate objects implementing the ServiceWorker interface across documents and workers can all be associated with the same service worker simultaneously.

A ServiceWorker object has an associated ServiceWorkerState object which is itself associated with service worker's state.

3.1.1. Getting ServiceWorker instances

An environment settings object has a service worker object map, a map where the keys are service workers and the values are ServiceWorker objects.

To get the service worker object representing serviceWorker (a service worker) in environment (an environment settings object), run these steps:
  1. Let objectMap be environment’s service worker object map.

  2. If objectMap[serviceWorker] does not exist, then:

    1. Let serviceWorkerObj be a new ServiceWorker in environment’s Realm, and associate it with serviceWorker.

    2. Set serviceWorkerObj’s state to serviceWorker’s state.

    3. Set objectMap[serviceWorker] to serviceWorkerObj.

  3. Return objectMap[serviceWorker].

3.1.2. scriptURL

The scriptURL attribute must return the service worker's serialized script url.

For example, consider a document created by a navigation to https://example.com/app.html which matches via the following registration call which has been previously executed:
// Script on the page https://example.com/app.html
navigator.serviceWorker.register("/service_worker.js");

The value of navigator.serviceWorker.controller.scriptURL will be "https://example.com/service_worker.js".

3.1.3. state

The state attribute must return the value (in ServiceWorkerState enumeration) to which it was last set.

3.1.4. postMessage(message, transfer)

The postMessage(message, transfer) method must run these steps:

  1. Let serviceWorker be the service worker represented by the context object.

  2. Let incumbentSettings be the incumbent settings object.

  3. Let incumbentGlobal be incumbentSettings’s global object.

  4. Let serializeWithTransferResult be StructuredSerializeWithTransfer(message, transfer). Rethrow any exceptions.

  5. If the result of running the Should Skip Event algorithm with "message" and serviceWorker is true, then return.

  6. Run these substeps in parallel:

    1. If the result of running the Run Service Worker algorithm with serviceWorker is failure, then return.

    2. Queue a task on the DOM manipulation task source to run the following steps:

      1. Let source be determined by switching on the type of incumbentGlobal:

        ServiceWorkerGlobalScope
        The result of getting the service worker object that represents incumbentGlobal’s service worker in the relevant settings object of serviceWorker’s global object.
        Window
        a new WindowClient object that represents incumbentGlobal’s relevant settings object.
        Otherwise
        a new Client object that represents incumbentGlobal’s associated worker
      2. Let origin be the serialization of incumbentSettings’s origin.

      3. Let destination be the ServiceWorkerGlobalScope object associated with serviceWorker.

      4. Let deserializeRecord be StructuredDeserializeWithTransfer(serializeWithTransferResult, destination’s Realm).

        If this throws an exception, catch it, fire an event named messageerror at destination, using MessageEvent, with the origin attribute initialized to origin and the source attribute initialized to source, and then abort these steps.

      5. Let messageClone be deserializeRecord.[[Deserialized]].

      6. Let newPorts be a new frozen array consisting of all MessagePort objects in deserializeRecord.[[TransferredValues]], if any, maintaining their relative order.

      7. Let e be the result of creating an event named message, using ExtendableMessageEvent, with the origin attribute initialized to origin, the source attribute initialized to source, the data attribute initialized to messageClone, and the ports attribute initialized to newPorts.

      8. Dispatch e at destination.

      9. Invoke Update Service Worker Extended Events Set with serviceWorker and e.

3.1.5. Event handler

The following is the event handler (and its corresponding event handler event type) that must be supported, as event handler IDL attributes, by all objects implementing ServiceWorker interface:

event handler event handler event type
onstatechange statechange

3.2. ServiceWorkerRegistration

[SecureContext, Exposed=(Window,Worker)]
interface ServiceWorkerRegistration : EventTarget {
  readonly attribute ServiceWorker? installing;
  readonly attribute ServiceWorker? waiting;
  readonly attribute ServiceWorker? active;

  readonly attribute USVString scope;
  readonly attribute ServiceWorkerUpdateViaCache updateViaCache;

  [NewObject] Promise<void> update();
  [NewObject] Promise<boolean> unregister();

  // event
  attribute EventHandler onupdatefound;
};

enum ServiceWorkerUpdateViaCache {
  "imports",
  "all",
  "none"
};

A ServiceWorkerRegistration has a service worker registration (a service worker registration).

3.2.1. Getting ServiceWorkerRegistration instances

An environment settings object has a service worker registration object map, a map where the keys are service worker registrations and the values are ServiceWorkerRegistration objects.

To get the service worker registration object representing registration (a service worker registration) in environment (an environment settings object), run these steps:
  1. Let objectMap be environment’s service worker registration object map.

  2. If objectMap[registration] does not exist, then:

    1. Let registrationObject be a new ServiceWorkerRegistration in environment’s Realm.

    2. Set registrationObject’s service worker registration to registration.

    3. Set registrationObject’s installing attribute to null.

    4. Set registrationObject’s waiting attribute to null.

    5. Set registrationObject’s active attribute to null.

    6. If registration’s installing worker is not null, then set registrationObject’s installing attribute to the result of getting the service worker object that represents registration’s installing worker in environment.

    7. If registration’s waiting worker is not null, then set registrationObject’s waiting attribute to the result of getting the service worker object that represents registration’s waiting worker in environment.

    8. If registration’s active worker is not null, then set registrationObject’s active attribute to the result of getting the service worker object that represents registration’s active worker in environment.

    9. Set objectMap[registration] to registrationObject.

  3. Return objectMap[registration].

installing attribute must return the value to which it was last set.

Note: Within a Realm, there is only one ServiceWorker object per associated service worker.

waiting attribute must return the value to which it was last set.

Note: Within a Realm, there is only one ServiceWorker object per associated service worker.

active attribute must return the value to which it was last set.

Note: Within a Realm, there is only one ServiceWorker object per associated service worker.

3.2.5. scope

The scope attribute must return service worker registration's serialized scope url.

In the example in § 3.1.2 scriptURL, the value of registration.scope, obtained from navigator.serviceWorker.ready.then(registration => console.log(registration.scope)) for example, will be "https://example.com/".

3.2.6. updateViaCache

The updateViaCache attribute must return service worker registration's update via cache mode.

3.2.7. update()

update() method must run these steps:

  1. Let registration be the service worker registration.

  2. Let newestWorker be the result of running Get Newest Worker algorithm passing registration as its argument.

  3. If newestWorker is null, return a promise rejected with an "InvalidStateError" DOMException and abort these steps.

  4. If the context object’s relevant settings object’s global object globalObject is a ServiceWorkerGlobalScope object, and globalObject’s associated service worker's state is "installing", return a promise rejected with an "InvalidStateError" DOMException and abort these steps.

  5. Let promise be a promise.

  6. Let job be the result of running Create Job with update, registration’s scope url, newestWorker’s script url, promise, and the context object’s relevant settings object.

  7. Set job’s worker type to newestWorker’s type.

  8. Invoke Schedule Job with job.

  9. Return promise.

Note: The unregister() method unregisters the service worker registration. It is important to note that the currently controlled service worker client's active service worker's containing service worker registration is effective until all the service worker clients (including itself) using this service worker registration unload. That is, the unregister() method only affects subsequent navigations.

unregister() method must run these steps:

  1. Let promise be a new promise.

  2. Let job be the result of running Create Job with unregister, the scope url of the service worker registration, null, promise, and the context object’s relevant settings object.

  3. Invoke Schedule Job with job.

  4. Return promise.

3.2.9. Event handler

The following is the event handler (and its corresponding event handler event type) that must be supported, as event handler IDL attributes, by all objects implementing ServiceWorkerRegistration interface:

event handler event handler event type
onupdatefound updatefound
partial interface Navigator {
  [SecureContext, SameObject] readonly attribute ServiceWorkerContainer serviceWorker;
};

partial interface WorkerNavigator {
  [SecureContext, SameObject] readonly attribute ServiceWorkerContainer serviceWorker;
};

The serviceWorker attribute must return the ServiceWorkerContainer object that is associated with the context object.

3.4. ServiceWorkerContainer

[SecureContext, Exposed=(Window,Worker)]
interface ServiceWorkerContainer : EventTarget {
  readonly attribute ServiceWorker? controller;
  readonly attribute Promise<ServiceWorkerRegistration> ready;

  [NewObject] Promise<ServiceWorkerRegistration> register(USVString scriptURL, optional RegistrationOptions options = {});

  [NewObject] Promise<any> getRegistration(optional USVString clientURL = "");
  [NewObject] Promise<FrozenArray<ServiceWorkerRegistration>> getRegistrations();

  void startMessages();


  // events
  attribute EventHandler oncontrollerchange;
  attribute EventHandler onmessage; // event.source of message events is ServiceWorker object
  attribute EventHandler onmessageerror;
};
dictionary RegistrationOptions {
  USVString scope;
  WorkerType type = "classic";
  ServiceWorkerUpdateViaCache updateViaCache = "imports";
};

The user agent must create a ServiceWorkerContainer object when a Navigator object or a WorkerNavigator object is created and associate it with that object.

A ServiceWorkerContainer provides capabilities to register, unregister, and update the service worker registrations, and provides access to the state of the service worker registrations and their associated service workers.

A ServiceWorkerContainer has an associated service worker client, which is a service worker client whose global object is associated with the Navigator object or the WorkerNavigator object that the ServiceWorkerContainer is retrieved from.

A ServiceWorkerContainer object has an associated ready promise (a promise). It is initially set to a new promise.

A ServiceWorkerContainer object has a task source called the client message queue, initially empty. A client message queue can be enabled or disabled, and is initially disabled. When a ServiceWorkerContainer object’s client message queue is enabled, the event loop must use it as one of its task sources. When the ServiceWorkerContainer object’s relevant global object is a Window object, all tasks queued on its client message queue must be associated with its relevant settings object’s responsible document.

controller attribute must run these steps:

  1. Let client be the context object’s service worker client.

  2. If client’s active service worker is null, then return null.

  3. Return the result of getting the service worker object that represents client’s active service worker in the context object's relevant settings object.

Note: navigator.serviceWorker.controller returns null if the request is a force refresh (shift+refresh).

ready attribute must run these steps:

  1. Let readyPromise be the context object's ready promise.

  2. If readyPromise is pending, run the following substeps in parallel:

    1. Let registration be the result of running Match Service Worker Registration with the context object's service worker client's creation URL.

    2. If registration is not null, and registration’s active worker is not null, queue a task on readyPromise’s relevant settings object's responsible event loop, using the DOM manipulation task source, to resolve readyPromise with the result of getting the service worker registration object that represents registration in readyPromise’s relevant settings object.

  3. Return readyPromise.

Note: The returned ready promise will never reject. If it does not resolve in this algorithm, it will eventually resolve when a matching service worker registration is registered and its active worker is set. (See the relevant Activate algorithm step.)

Note: The register(scriptURL, options) method creates or updates a service worker registration for the given scope url. If successful, a service worker registration ties the provided scriptURL to a scope url, which is subsequently used for navigation matching.

register(scriptURL, options) method must run these steps:

  1. Let p be a promise.

  2. Let client be the context object’s service worker client.

  3. Let scriptURL be the result of parsing scriptURL with the context object’s relevant settings object’s API base URL.

  4. If scriptURL is failure, reject p with a TypeError and abort these steps.

  5. Set scriptURL’s fragment to null.

    Note: The user agent does not store the fragment of the script’s url. This means that the fragment does not have an effect on identifying service workers.

  6. If scriptURL’s scheme is not one of "http" and "https", reject p with a TypeError and abort these steps.

  7. If any of the strings in scriptURL’s path contains either ASCII case-insensitive "%2f" or ASCII case-insensitive "%5c", reject p with a TypeError and abort these steps.

  8. Let scopeURL be null.

  9. If options.scope is not present, set scopeURL to the result of parsing a string "./" with scriptURL.

    Note: The scope url for the registration is set to the location of the service worker script by default.

  10. Else, set scopeURL to the result of parsing options.scope with the context object’s relevant settings object’s API base URL.

  11. If scopeURL is failure, reject p with a TypeError and abort these steps.

  12. Set scopeURL’s fragment to null.

    Note: The user agent does not store the fragment of the scope url. This means that the fragment does not have an effect on identifying service worker registrations.

  13. If scopeURL’s scheme is not one of "http" and "https", reject p with a TypeError and abort these steps.

  14. If any of the strings in scopeURL’s path contains either ASCII case-insensitive "%2f" or ASCII case-insensitive "%5c", reject p with a TypeError and abort these steps.

  15. Let job be the result of running Create Job with register, scopeURL, scriptURL, p, and client.

  16. Set job’s worker type to options.type.

  17. Set job’s update via cache mode to options.updateViaCache.

  18. Invoke Schedule Job with job.

  19. Return p.

getRegistration(clientURL) method must run these steps:

  1. Let client be the context object’s service worker client.

  2. Let clientURL be the result of parsing clientURL with the context object’s relevant settings object’s API base URL.

  3. If clientURL is failure, return a promise rejected with a TypeError.

  4. Set clientURL’s fragment to null.

  5. If the origin of clientURL is not client’s origin, return a promise rejected with a "SecurityError" DOMException.

  6. Let promise be a new promise.

  7. Run the following substeps in parallel:

    1. Let registration be the result of running Match Service Worker Registration algorithm with clientURL as its argument.

    2. If registration is null, resolve promise with undefined and abort these steps.

    3. Resolve promise with the result of getting the service worker registration object that represents registration in promise’s relevant settings object.

  8. Return promise.

getRegistrations() method must run these steps:

  1. Let client be the context object's service worker client.

  2. Let promise be a new promise.

  3. Run the following steps in parallel:

    1. Let registrations be a new list.

    2. For each scoperegistration of scope to registration map:

      1. If the origin of the result of parsing scope is the same as client’s origin, then append registration to registrations.

    3. Queue a task on promise’s relevant settings object's responsible event loop, using the DOM manipulation task source, to run the following steps:

      1. Let registrationObjects be a new list.

      2. For each registration of registrations:

        1. Let registrationObj be the result of getting the service worker registration object that represents registration in promise’s relevant settings object.

        2. Append registrationObj to registrationObjects.

      3. Resolve promise with a new frozen array of registrationObjects in promise’s relevant Realm.

  4. Return promise.

startMessages() method must enable the context object’s client message queue if it is not enabled.

3.4.7. Event handlers

The following are the event handlers (and their corresponding event handler event types) that must be supported, as event handler IDL attributes, by all objects implementing the ServiceWorkerContainer interface:

event handler event handler event type
oncontrollerchange controllerchange
onmessage message
onmessageerror messageerror

The first time the context object’s onmessage IDL attribute is set, its client message queue must be enabled.

3.5. Events

The following event is dispatched on ServiceWorker object:

Event name Interface Dispatched when…
statechange Event The state attribute of the ServiceWorker object is changed.

The following event is dispatched on ServiceWorkerRegistration object:

Event name Interface Dispatched when…
updatefound Event The service worker registration's installing worker changes. (See step 8 of the Install algorithm.)

The following events are dispatched on ServiceWorkerContainer object:

Event name Interface Dispatched when…
controllerchange Event The service worker client's active service worker changes. (See step 9.2 of the Activate algorithm. The skip waiting flag of a service worker causes activation of the service worker registration to occur while service worker clients are using the service worker registration, navigator.serviceWorker.controller immediately reflects the active worker as the service worker that controls the service worker client.)

4. Execution Context

Serving Cached Resources:
// caching.js
self.addEventListener("install", event => {
  event.waitUntil(
    // Open a cache of resources.
    caches.open("shell-v1").then(cache => {
      // Begins the process of fetching them.
      // The coast is only clear when all the resources are ready.
      return cache.addAll([
        "/app.html",
        "/assets/v1/base.css",
        "/assets/v1/app.js",
        "/assets/v1/logo.png",
        "/assets/v1/intro_video.webm"
      ]);
    })
  );
});

self.addEventListener("fetch", event => {
  // No "fetch" events are dispatched to the service worker until it
  // successfully installs and activates.

  // All operations on caches are async, including matching URLs, so we use
  // promises heavily. e.respondWith() even takes promises to enable this:
  event.respondWith(
    caches.match(e.request).then(response => {
      return response || fetch(e.request);
    }).catch(() => {
      return caches.match("/fallback.html");
    })
  );
});

4.1. ServiceWorkerGlobalScope

[Global=(Worker,ServiceWorker), Exposed=ServiceWorker]
interface ServiceWorkerGlobalScope : WorkerGlobalScope {
  [SameObject] readonly attribute Clients clients;
  [SameObject] readonly attribute ServiceWorkerRegistration registration;

  [NewObject] Promise<void> skipWaiting();

  attribute EventHandler oninstall;
  attribute EventHandler onactivate;
  attribute EventHandler onfetch;

  attribute EventHandler onmessage;
  attribute EventHandler onmessageerror;
};

A ServiceWorkerGlobalScope object represents the global execution context of a service worker. A ServiceWorkerGlobalScope object has an associated service worker (a service worker). A ServiceWorkerGlobalScope object has an associated force bypass cache for import scripts flag. It is initially unset.

Note: ServiceWorkerGlobalScope object provides generic, event-driven, time-limited script execution contexts that run at an origin. Once successfully registered, a service worker is started, kept alive and killed by their relationship to events, not service worker clients. Any type of synchronous requests must not be initiated inside of a service worker.

4.1.1. clients

The clients attribute must return the Clients object that is associated with the context object.

4.1.2. registration

The registration attribute must return the result of getting the service worker registration object representing the context object's service worker's containing service worker registration in context object's relevant settings object.

4.1.3. skipWaiting()

Note: The skipWaiting() method allows this service worker to progress from the registration's waiting position to active even while service worker clients are using the registration.

skipWaiting() method must run these steps:

  1. Let promise be a new promise.

  2. Run the following substeps in parallel:

    1. Set service worker's skip waiting flag.

    2. Invoke Try Activate with service worker's containing service worker registration.

    3. Resolve promise with undefined.

  3. Return promise.

4.1.4. Event handlers

The following are the event handlers (and their corresponding event handler event types) that must be supported, as event handler IDL attributes, by all objects implementing the ServiceWorkerGlobalScope interface:

event handler event handler event type
oninstall install
onactivate activate
onfetch fetch
onmessage message
onmessageerror messageerror

4.2. Client

[Exposed=ServiceWorker]
interface Client {
  readonly attribute USVString url;
  readonly attribute FrameType frameType;
  readonly attribute DOMString id;
  readonly attribute ClientType type;
  void postMessage(any message, optional sequence<object> transfer = []);
};

[Exposed=ServiceWorker]
interface WindowClient : Client {
  readonly attribute VisibilityState visibilityState;
  readonly attribute boolean focused;
  [SameObject] readonly attribute FrozenArray<USVString> ancestorOrigins;
  [NewObject] Promise<WindowClient> focus();
  [NewObject] Promise<WindowClient?> navigate(USVString url);
};

enum FrameType {
  "auxiliary",
  "top-level",
  "nested",
  "none"
};

A Client object has an associated service worker client (a service worker client).

A Client object has an associated frame type, which is one of "auxiliary", "top-level", "nested", and "none". Unless stated otherwise it is "none".

A WindowClient object has an associated browsing context, which is its service worker client's global object's browsing context.

A WindowClient object has an associated visibility state, which is one of visibilityState attribute value.

A WindowClient object has an associated focus state, which is either true or false (initially false).

A WindowClient object has an associated ancestor origins array.

4.2.1. url

The url attribute must return the context object’s associated service worker client's serialized creation URL.

4.2.2. frameType

The frameType attribute must return the context object's frame type.

4.2.3. id

The id attribute must return its associated service worker client's id.

4.2.4. type

The type attribute must run these steps:

  1. Let client be context object's service worker client.

  2. If client is an environment settings object, then:

    1. If client is a window client, return "window".

    2. Else if client is a dedicated worker client, return "worker".

    3. Else if client is a shared worker client, return "sharedworker".

  3. Else:

    1. Return "window".

4.2.5. postMessage(message, transfer)

The postMessage(message, transfer) method must run these steps:

  1. Let contextObject be the context object.

  2. Let sourceSettings be the contextObject’s relevant settings object.

  3. Let serializeWithTransferResult be StructuredSerializeWithTransfer(message, transfer). Rethrow any exceptions.

  4. Run the following steps in parallel:

    1. Let targetClient be null.

    2. For each service worker client client:

      1. If client is the contextObject’s service worker client, set targetClient to client, and break.

    3. If targetClient is null, return.

    4. Let destination be the ServiceWorkerContainer object whose associated service worker client is targetClient.

    5. Add a task that runs the following steps to destination’s client message queue:

      1. Let origin be the serialization of sourceSettings’s origin.

      2. Let source be the result of getting the service worker object that represents contextObject’s relevant global object's service worker in targetClient.

      3. Let deserializeRecord be StructuredDeserializeWithTransfer(serializeWithTransferResult, destination’s relevant Realm).

        If this throws an exception, catch it, fire an event named messageerror at destination, using MessageEvent, with the origin attribute initialized to origin and the source attribute initialized to source, and then abort these steps.

      4. Let messageClone be deserializeRecord.[[Deserialized]].

      5. Let newPorts be a new frozen array consisting of all MessagePort objects in deserializeRecord.[[TransferredValues]], if any.

      6. Dispatch an event named message at destination, using MessageEvent, with the origin attribute initialized to origin, the source attribute initialized to source, the data attribute initialized to messageClone, and the ports attribute initialized to newPorts.

4.2.6. visibilityState

The visibilityState attribute must return the context object’s visibility state.

4.2.7. focused

The focused attribute must return the context object’s focus state.

4.2.8. ancestorOrigins

The ancestorOrigins attribute must return the context object’s associated ancestor origins array.

4.2.9. focus()

The focus() method must run these steps:

  1. If this algorithm is not triggered by user activation, return a promise rejected with an "InvalidAccessError" DOMException.

  2. Let serviceWorkerEventLoop be the current global object's event loop.

  3. Let promise be a new promise.

  4. Queue a task to run the following steps on the context object's associated service worker client's responsible event loop using the user interaction task source:

    1. Run the focusing steps with the context object's browsing context.

    2. Let frameType be the result of running Get Frame Type with the context object's browsing context.

    3. Let visibilityState be the context object's browsing context's active document's visibilityState attribute value.

    4. Let focusState be the result of running the has focus steps with the context object's browsing context's active document.

    5. Let ancestorOriginsList be the context object's browsing context's active document's relevant global object's Location object’s ancestor origins list's associated list.

    6. Queue a task to run the following steps on serviceWorkerEventLoop using the DOM manipulation task source:

      1. Let windowClient be the result of running Create Window Client with the context object's associated service worker client, frameType, visibilityState, focusState, and ancestorOriginsList.

      2. If windowClient’s focus state is true, resolve promise with windowClient.

      3. Else, reject promise with a TypeError.

  5. Return promise.

4.2.10. navigate(url)

The navigate(url) method must run these steps:

  1. Let url be the result of parsing url with the context object’s relevant settings object’s API base URL.

  2. If url is failure, return a promise rejected with a TypeError.

  3. If url is about:blank, return a promise rejected with a TypeError.

  4. If the context object’s associated service worker client's active service worker is not the context object’s relevant global object’s service worker, return a promise rejected with a TypeError.

  5. Let serviceWorkerEventLoop be the current global object's event loop.

  6. Let promise be a new promise.

  7. Queue a task to run the following steps on the context object's associated service worker client's responsible event loop using the user interaction task source:

    1. Let browsingContext be the context object's browsing context.

    2. If browsingContext has discarded its Document, queue a task to reject promise with a TypeError, on serviceWorkerEventLoop using the DOM manipulation task source, and abort these steps.

    3. HandleNavigate: Navigate browsingContext to url with exceptions enabled. The source browsing context must be browsingContext.

    4. If the algorithm steps invoked in the step labeled HandleNavigate throws an exception, queue a task to reject promise with the exception, on serviceWorkerEventLoop using the DOM manipulation task source, and abort these steps.

    5. Let frameType be the result of running Get Frame Type with browsingContext.

    6. Let visibilityState be browsingContext’s active document’s visibilityState attribute value.

    7. Let focusState be the result of running the has focus steps with browsingContext’s active document.

    8. Let ancestorOriginsList be browsingContext’s active document's relevant global object's Location object’s ancestor origins list's associated list.

    9. Queue a task to run the following steps on serviceWorkerEventLoop using the DOM manipulation task source:

      1. If browsingContext’s Window object’s environment settings object’s creation URL’s origin is not the same as the service worker's origin, resolve promise with null and abort these steps.

      2. Let windowClient be the result of running Create Window Client with the context object's service worker client, frameType, visibilityState, focusState, and ancestorOriginsList.

      3. Resolve promise with windowClient.

  8. Return promise.

4.3. Clients

[Exposed=ServiceWorker]
interface Clients {
  // The objects returned will be new instances every time
  [NewObject] Promise<any> get(DOMString id);
  [NewObject] Promise<FrozenArray<Client>> matchAll(optional ClientQueryOptions options = {});
  [NewObject] Promise<WindowClient?> openWindow(USVString url);
  [NewObject] Promise<void> claim();
};
dictionary ClientQueryOptions {
  boolean includeUncontrolled = false;
  ClientType type = "window";
};
enum ClientType {
  "window",
  "worker",
  "sharedworker",
  "all"
};

The user agent must create a Clients object when a ServiceWorkerGlobalScope object is created and associate it with that object.

4.3.1. get(id)

The get(id) method must run these steps:

  1. Let promise be a new promise.

  2. Run these substeps in parallel:

    1. For each service worker client client whose origin is the same as the associated service worker's origin:

      1. If client’s id is not id, continue.

      2. Wait for either client’s execution ready flag to be set or for client’s discarded flag to be set.

      3. If client’s execution ready flag is set, then invoke Resolve Get Client Promise with client and promise, and abort these steps.

    2. Resolve promise with undefined.

  3. Return promise.

4.3.2. matchAll(options)

The matchAll(options) method must run these steps:

  1. Let promise be a new promise.

  2. Run the following steps in parallel:

    1. Let targetClients be a new list.

    2. For each service worker client client whose origin is the same as the associated service worker's origin:

      1. If client’s execution ready flag is unset or client’s discarded flag is set, continue.

      2. If client is not a secure context, continue.

      3. If options["includeUncontrolled"] is false, and if client’s active service worker is not the associated service worker, continue.

      4. Add client to targetClients.

    3. Let matchedWindowData be a new list.

    4. Let matchedClients be a new list.

    5. For each service worker client client in targetClients:

      1. If options["type"] is "window" or "all", and client is not an environment settings object or is a window client, then:

        1. Let windowData be «[ "client" → client, "ancestorOriginsList" → a new list ]».

        2. Let browsingContext be null.

        3. Let isClientEnumerable be true.

        4. If client is an environment settings object, set browsingContext to client’s global object's browsing context.

        5. Else, set browsingContext to client’s target browsing context.

        6. Queue a task task to run the following substeps on browsingContext’s event loop using the user interaction task source:

          1. If browsingContext has been discarded, then set isClientEnumerable to false and abort these steps.

          2. If client is a window client and client’s responsible document is not browsingContext’s active document, then set isClientEnumerable to false and abort these steps.

          3. Set windowData["frameType"] to the result of running Get Frame Type with browsingContext.

          4. Set windowData["visibilityState"] to browsingContext’s active document's visibilityState attribute value.

          5. Set windowData["focusState"] to the result of running the has focus steps with browsingContext’s active document as the argument.

          6. If client is a window client, then set windowData["ancestorOriginsList"] to browsingContext’s active document's relevant global object's Location object’s ancestor origins list's associated list.

        7. Wait for task to have executed.

          Note: Wait is a blocking wait, but implementers may run the iterations in parallel as long as the state is not broken.

        8. If isClientEnumerable is true, then:

          1. Add windowData to matchedWindowData.

      2. Else if options["type"] is "worker" or "all" and client is a dedicated worker client, or options["type"] is "sharedworker" or "all" and client is a shared worker client, then:

        1. Add client to matchedClients.

    6. Queue a task to run the following steps on promise’s relevant settings object's responsible event loop using the DOM manipulation task source:

      1. Let clientObjects be a new list.

      2. For each windowData in matchedWindowData:

        1. Let windowClient be the result of running Create Window Client algorithm with windowData["client"], windowData["frameType"], windowData["visibilityState"], windowData["focusState"], and windowData["ancestorOriginsList"] as the arguments.

        2. Append windowClient to clientObjects.

      3. For each client in matchedClients:

        1. Let clientObject be the result of running Create Client algorithm with client as the argument.

        2. Append clientObject to clientObjects.

      4. Sort clientObjects such that:

        Note: Window clients are always placed before worker clients.

      5. Resolve promise with a new frozen array of clientObjects in promise’s relevant Realm.

  3. Return promise.

4.3.3. openWindow(url)

The openWindow(url) method must run these steps:

  1. Let url be the result of parsing url with the context object’s relevant settings object’s API base URL.

  2. If url is failure, return a promise rejected with a TypeError.

  3. If url is about:blank, return a promise rejected with a TypeError.

  4. If this algorithm is not triggered by user activation, return a promise rejected with an "InvalidAccessError" DOMException.

  5. Let serviceWorkerEventLoop be the current global object's event loop.

  6. Let promise be a new promise.

  7. Run these substeps in parallel:

    1. Let newContext be a new top-level browsing context.

    2. Queue a task to run the following steps on newContext’s Window object’s environment settings object's responsible event loop using the user interaction task source:

      1. HandleNavigate: Navigate newContext to url with exceptions enabled and replacement enabled.

      2. If the algorithm steps invoked in the step labeled HandleNavigate throws an exception, queue a task to reject promise with the exception, on serviceWorkerEventLoop using the DOM manipulation task source, and abort these steps.

      3. Let frameType be the result of running Get Frame Type with newContext.

      4. Let visibilityState be newContext’s active document’s visibilityState attribute value.

      5. Let focusState be the result of running the has focus steps with newContext’s active document as the argument.

      6. Let ancestorOriginsList be newContext’s active document’s relevant global object’s Location object’s ancestor origins list's associated list.

      7. Queue a task to run the following steps on serviceWorkerEventLoop using the DOM manipulation task source:

        1. If newContext’s Window object’s environment settings object's creation URL's origin is not the same as the service worker's origin, resolve promise with null and abort these steps.

        2. Let client be the result of running Create Window Client with newContext’s Window object’s environment settings object, frameType, visibilityState, focusState, and ancestorOriginsList as the arguments.

        3. Resolve promise with client.

  8. Return promise.

4.3.4. claim()

The claim() method must run these steps:

  1. If the service worker is not an active worker, return a promise rejected with an "InvalidStateError" DOMException.

  2. Let promise be a new promise.

  3. Run the following substeps in parallel:

    1. For each service worker client client whose origin is the same as the service worker's origin:

      1. If client’s execution ready flag is unset or client’s discarded flag is set, continue.

      2. If client is not a secure context, continue.

      3. Let registration be the result of running Match Service Worker Registration algorithm passing client’s creation URL as the argument.

      4. If registration is not the service worker's containing service worker registration, continue.

        Note: registration will be null if the service worker's containing service worker registration is unregistered.

      5. If client’s active service worker is not the service worker, then:

        1. Invoke Handle Service Worker Client Unload with client as the argument.

        2. Set client’s active service worker to service worker.

        3. Invoke Notify Controller Change algorithm with client as the argument.

    2. Resolve promise with undefined.

  4. Return promise.

4.4. ExtendableEvent

[Exposed=ServiceWorker]
interface ExtendableEvent : Event {
  constructor(DOMString type, optional ExtendableEventInit eventInitDict = {});
  void waitUntil(Promise<any> f);
};
dictionary ExtendableEventInit : EventInit {
  // Defined for the forward compatibility across the derived events
};

An ExtendableEvent object has an associated extend lifetime promises (an array of promises). It is initially an empty array.

An ExtendableEvent object has an associated pending promises count (the number of pending promises in the extend lifetime promises). It is initially set to zero.

An ExtendableEvent object has an associated timed out flag. It is initially unset, and is set after an optional user agent imposed delay if the pending promises count is greater than zero.

An ExtendableEvent object is said to be active when its timed out flag is unset and either its pending promises count is greater than zero or its dispatch flag is set.

Service workers have two lifecycle events, install and activate. Service workers use the ExtendableEvent interface for activate event and install event.

Service worker extensions that define event handlers may also use or extend the ExtendableEvent interface.

4.4.1. event.waitUntil(f)

Note: waitUntil() method extends the lifetime of the event.

waitUntil(f) method must run these steps:

  1. Let event be the context object.

  2. Add lifetime promise f to event.

To add lifetime promise promise (a promise) to event (an ExtendableEvent), run these steps:
  1. If event’s isTrusted attribute is false, throw an "InvalidStateError" DOMException.

  2. If event is not active, throw an "InvalidStateError" DOMException.

    Note: If no lifetime extension promise has been added in the task that called the event handlers, calling waitUntil() in subsequent asynchronous tasks will throw.

  3. Add promise to event’s extend lifetime promises.

  4. Increment event’s pending promises count by one.

    Note: The pending promises count is incremented even if the given promise has already been settled. The corresponding count decrement is done in the microtask queued by the reaction to the promise.

  5. Upon fulfillment or rejection of promise, queue a microtask to run these substeps:

    1. Decrement event’s pending promises count by one.

    2. If event’s pending promises count is 0, then:

      1. Let registration be the current global object's associated service worker's containing service worker registration.

      2. If registration is unregistered, invoke Try Clear Registration with registration.

      3. If registration is not null, invoke Try Activate with registration.

The user agent should not terminate a service worker if Service Worker Has No Pending Events returns false for that service worker.

Service workers and extensions that define event handlers may define their own behaviors, allowing the extend lifetime promises to suggest operation length, and the rejected state of any of the promise in extend lifetime promises to suggest operation failure.

Note: Service workers delay treating the installing worker as "installed" until all the promises in the install event’s extend lifetime promises resolve successfully. (See the relevant Install algorithm step.) If any of the promises rejects, the installation fails. This is primarily used to ensure that a service worker is not considered "installed" until all of the core caches it depends on are populated. Likewise, service workers delay treating the active worker as "activated" until all the promises in the activate event’s extend lifetime promises settle. (See the relevant Activate algorithm step.) This is primarily used to ensure that any functional events are not dispatched to the service worker until it upgrades database schemas and deletes the outdated cache entries.

4.5. FetchEvent

[Exposed=ServiceWorker]
interface FetchEvent : ExtendableEvent {
  constructor(DOMString type, FetchEventInit eventInitDict);
  [SameObject] readonly attribute Request request;
  readonly attribute DOMString clientId;

  void respondWith(Promise<Response> r);
};
dictionary FetchEventInit : ExtendableEventInit {
  required Request request;
  DOMString clientId = "";
};

Service workers have an essential functional event fetch. For fetch event, service workers use the FetchEvent interface which extends the ExtendableEvent interface.

Each event using FetchEvent interface has an associated potential response (a response), initially set to null, and the following associated flags that are initially unset:

  • wait to respond flag

  • respond-with entered flag

  • respond-with error flag

4.5.1. event.request

request attribute must return the value it was initialized to.

4.5.2. event.clientId

clientId attribute must return the value it was initialized to. When an event is created the attribute must be initialized to the empty string.

4.5.3. event.respondWith(r)

Note: Developers can set the argument r with either a promise that resolves with a Response object or a Response object (which is automatically cast to a promise). Otherwise, a network error is returned to Fetch. Renderer-side security checks about tainting for cross-origin content are tied to the types of filtered responses defined in Fetch.

respondWith(r) method must run these steps:

  1. Let event be the context object.

  2. If event’s dispatch flag is unset, throw an "InvalidStateError" DOMException.

  3. If event’s respond-with entered flag is set, throw an "InvalidStateError" DOMException.

  4. Add lifetime promise r to event.

    Note: event.respondWith(r) extends the lifetime of the event by default as if event.waitUntil(r) is called.

  5. Set event’s stop propagation flag and stop immediate propagation flag.

  6. Set event’s respond-with entered flag.

  7. Set event’s wait to respond flag.

  8. Let targetRealm be event’s relevant Realm.

  9. Upon rejection of r:

    1. Set event’s respond-with error flag.

    2. Unset event’s wait to respond flag.

  10. Upon fulfillment of r with response:

    1. If response is not a Response object, then set the respond-with error flag.

      Note: If the respond-with error flag is set, a network error is returned to Fetch through Handle Fetch algorithm. (See the step 21.1.) Otherwise, the value response is returned to Fetch through Handle Fetch algorithm. (See the step 22.1.)

    2. Else:

      1. Let bytes be an empty byte sequence.

      2. Let end-of-body be false.

      3. Let done be false.

      4. Let potentialResponse be a copy of response’s associated response, except for its body.

      5. If response’s body is non-null, run these substeps:

        1. Let reader be the result of getting a reader from response’s body's stream.

        2. Let highWaterMark be a non-negative, non-NaN number, chosen by the user agent.

        3. Let sizeAlgorithm be an algorithm that accepts a chunk object and returns a non-negative, non-NaN, non-infinite number, chosen by the user agent.

        4. Let pull be an action that runs these subsubsteps:

          1. Let promise be the result of reading a chunk from response’s body's stream with reader.

          2. When promise is fulfilled with an object whose done property is false and whose value property is a Uint8Array object, append the bytes represented by the value property to bytes and perform ! DetachArrayBuffer with the ArrayBuffer object wrapped by the value property.

          3. When promise is fulfilled with an object whose done property is true, set end-of-body to true.

          4. When promise is fulfilled with a value that matches with neither of the above patterns, or promise is rejected, error newStream with a TypeError.

        5. Let cancel be an action that cancels response’s body's stream with reader.

        6. Let newStream be the result of construct a ReadableStream object with highWaterMark, sizeAlgorithm, pull, and cancel in targetRealm.

        7. Set potentialResponse’s body to a new body whose stream is newStream.

        8. Run these subsubsteps repeatedly in parallel while done is false:

          1. If newStream is errored, then set done to true.

          2. Otherwise, if bytes is empty and end-of-body is true, then close newStream and set done to true.

          3. Otherwise, if bytes is not empty, run these subsubsubsteps:

            1. Let chunk be a subsequence of bytes starting from the beginning of bytes.

            2. Remove chunk from bytes.

            3. Let buffer be an ArrayBuffer object created in targetRealm and containing chunk.

            4. Enqueue a Uint8Array object created in targetRealm and wrapping buffer to newStream.

        Note: These substeps are meant to produce the observable equivalent of "piping" response’s body's stream into potentialResponse.

      6. Set event’s potential response to potentialResponse.

    3. Unset event’s wait to respond flag.

4.6. ExtendableMessageEvent

[Exposed=ServiceWorker]
interface ExtendableMessageEvent : ExtendableEvent {
  constructor(DOMString type, optional ExtendableMessageEventInit eventInitDict = {});
  readonly attribute any data;
  readonly attribute USVString origin;
  readonly attribute DOMString lastEventId;
  [SameObject] readonly attribute (Client or ServiceWorker or MessagePort)? source;
  readonly attribute FrozenArray<MessagePort> ports;
};
dictionary ExtendableMessageEventInit : ExtendableEventInit {
  any data = null;
  USVString origin = "";
  DOMString lastEventId = "";
  (Client or ServiceWorker or MessagePort)? source = null;
  sequence<MessagePort> ports = [];
};

Service workers define the extendable message event to allow extending the lifetime of the event. For the message event, service workers use the ExtendableMessageEvent interface which extends the ExtendableEvent interface.

4.6.1. event.data

The data attribute must return the value it was initialized to. When the object is created, this attribute must be initialized to null. It represents the message being sent.

4.6.2. event.origin

The origin attribute must return the value it was initialized to. When the object is created, this attribute must be initialized to the empty string. It represents the origin of the service worker client that sent the message.

4.6.3. event.lastEventId

The lastEventId attribute must return the value it was initialized to. When the object is created, this attribute must be initialized to the empty string.

4.6.4. event.source

The source attribute must return the value it was initialized to. When the object is created, this attribute must be initialized to null. It represents the Client object from which the message is sent.

4.6.5. event.ports

The ports attribute must return the value it was initialized to. When the object is created, this attribute must be initialized to the empty array. It represents the MessagePort array being sent.

4.7. Events

The following events, called service worker events, are dispatched on ServiceWorkerGlobalScope object:

Event name Interface Category Dispatched when…
install ExtendableEvent Lifecycle The service worker's containing service worker registration’s installing worker changes. (See step 11.2 of the Install algorithm.)
activate ExtendableEvent Lifecycle The service worker's containing service worker registration’s active worker changes. (See step 12.2 of the Activate algorithm.)
fetch FetchEvent Functional The http fetch invokes Handle Fetch with request. As a result of performing Handle Fetch, the service worker returns a response to the http fetch. The response, represented by a Response object, can be retrieved from a Cache object or directly from network using self.fetch(input, init) method. (A custom Response object can be another option.)
push PushEvent Functional (See Firing a push event.)
notificationclick NotificationEvent Functional (See Activating a notification.)
notificationclose NotificationEvent Functional (See Closing a notification.)
sync SyncEvent Functional (See Firing a sync event.)
canmakepayment CanMakePaymentEvent Functional (See Handling a CanMakePaymentEvent.)
paymentrequest PaymentRequestEvent Functional (See Handling a PaymentRequestEvent.)
message ExtendableMessageEvent Legacy When it receives a message.
messageerror MessageEvent Legacy When it was sent a message that cannot be deserialized.

5. Caches

To allow authors to fully manage their content caches for offline use, the Window and the WorkerGlobalScope provide the asynchronous caching methods that open and manipulate Cache objects. An origin can have multiple, named Cache objects, whose contents are entirely under the control of scripts. Caches are not shared across origins, and they are completely isolated from the browser’s HTTP cache.

5.1. Constructs

A request response list is a list of pairs consisting of a request (a request) and a response (a response).

The relevant request response list is the instance that the context object represents.

A name to cache map is an ordered map whose entry consists of a key (a string that represents the name of a request response list) and a value (a request response list).

Each origin has an associated name to cache map.

The relevant name to cache map is the instance of the context object's associated global object's environment settings object's origin.

5.2. Understanding Cache Lifetimes

The Cache instances are not part of the browser’s HTTP cache. The Cache objects are exactly what authors have to manage themselves. The Cache objects do not get updated unless authors explicitly request them to be. The Cache objects do not expire unless authors delete the entries. The Cache objects do not disappear just because the service worker script is updated. That is, caches are not updated automatically. Updates must be manually managed. This implies that authors should version their caches by name and make sure to use the caches only from the version of the service worker that can safely operate on.

5.3. self.caches

partial interface WindowOrWorkerGlobalScope {
  [SecureContext, SameObject] readonly attribute CacheStorage caches;
};

5.3.1. caches

caches attribute must return this object’s associated CacheStorage object.

5.4. Cache

[SecureContext, Exposed=(Window,Worker)]
interface Cache {
  [NewObject] Promise<any> match(RequestInfo request, optional CacheQueryOptions options = {});
  [NewObject] Promise<FrozenArray<Response>> matchAll(optional RequestInfo request, optional CacheQueryOptions options = {});
  [NewObject] Promise<void> add(RequestInfo request);
  [NewObject] Promise<void> addAll(sequence<RequestInfo> requests);
  [NewObject] Promise<void> put(RequestInfo request, Response response);
  [NewObject] Promise<boolean> delete(RequestInfo request, optional CacheQueryOptions options = {});
  [NewObject] Promise<FrozenArray<Request>> keys(optional RequestInfo request, optional CacheQueryOptions options = {});
};
dictionary CacheQueryOptions {
  boolean ignoreSearch = false;
  boolean ignoreMethod = false;
  boolean ignoreVary = false;
};

A Cache object represents a request response list. Multiple separate objects implementing the Cache interface across documents and workers can all be associated with the same request response list simultaneously.

A cache batch operation is a struct that consists of:

5.4.1. match(request, options)

match(request, options) method must run these steps:

  1. Let promise be a new promise.

  2. Run these substeps in parallel:

    1. Let p be the result of running the algorithm specified in matchAll(request, options) method with request and options.

    2. Wait until p settles.

    3. If p rejects with an exception, then:

      1. Reject promise with that exception.

    4. Else if p resolves with an array, responses, then:

      1. If responses is an empty array, then:

        1. Resolve promise with undefined.

      2. Else:

        1. Resolve promise with the first element of responses.

  3. Return promise.

5.4.2. matchAll(request, options)

matchAll(request, options) method must run these steps:

  1. Let r be null.

  2. If the optional argument request is not omitted, then:

    1. If request is a Request object, then:

      1. Set r to request’s request.

      2. If r’s method is not `GET` and options.ignoreMethod is false, return a promise resolved with an empty array.

    2. Else if request is a string, then:

      1. Set r to the associated request of the result of invoking the initial value of Request as constructor with request as its argument. If this throws an exception, return a promise rejected with that exception.

  3. Let realm be the context object's relevant realm.

  4. Let promise be a new promise.

  5. Run these substeps in parallel:

    1. Let responses be an empty list.

    2. If the optional argument request is omitted, then:

      1. For each requestResponse of the relevant request response list:

        1. Add a copy of requestResponse’s response to responses.

    3. Else:

      1. Let requestResponses be the result of running Query Cache with r and options.

      2. For each requestResponse of requestResponses:

        1. Add a copy of requestResponse’s response to responses.

    4. Queue a task, on promise’s relevant settings object's responsible event loop using the DOM manipulation task source, to perform the following steps:

      1. Let responseList be a list.

      2. For each response of responses:

        1. Add a new Response object associated with response and a new Headers object whose guard is "immutable" to responseList.

      3. Resolve promise with a frozen array created from responseList, in realm.

  6. Return promise.

5.4.3. add(request)

add(request) method must run these steps:

  1. Let requests be an array containing only request.

  2. Let responseArrayPromise be the result of running the algorithm specified in addAll(requests) passing requests as the argument.

  3. Return the result of reacting to responseArrayPromise with a fulfillment handler that returns undefined.

5.4.4. addAll(requests)

addAll(requests) method must run these steps:

  1. Let responsePromises be an empty list.

  2. Let requestList be an empty list.

  3. For each request whose type is Request in requests:

    1. Let r be request’s request.

    2. If r’s url's scheme is not one of "http" and "https", or r’s method is not `GET`, return a promise rejected with a TypeError.

  4. For each request in requests:

    1. Let r be the associated request of the result of invoking the initial value of Request as constructor with request as its argument. If this throws an exception, return a promise rejected with that exception.

    2. If r’s url's scheme is not one of "http" and "https", then:

      1. Terminate all the ongoing fetches initiated by requests with the aborted flag set.

      2. Return a promise rejected with a TypeError.

    3. If r’s client's global object is a ServiceWorkerGlobalScope object, set request’s service-workers mode to "foreign".

    4. Set r’s initiator to "fetch" and destination to "subresource".

    5. Add r to requestList.

    6. Let responsePromise be a new promise.

    7. Run the following substeps in parallel:

      • Fetch r.

      • To process response for response, run these substeps:

        1. If response’s type is "error", or response’s status is not an ok status or is 206, reject responsePromise with a TypeError.

        2. Else if response’s header list contains a header named `Vary`, then:

          1. Let fieldValues be the list containing the elements corresponding to the field-values of the Vary header.

          2. For each fieldValue of fieldValues:

            1. If fieldValue matches "*", then:

              1. Reject responsePromise with a TypeError.

              2. Terminate all the ongoing fetches initiated by requests with the aborted flag set.

              3. Abort these steps.

      • To process response end-of-body for response, run these substeps:

        1. If response’s aborted flag is set, reject responsePromise with an "AbortError" DOMException and abort these steps.

        2. Resolve responsePromise with response.

        Note: The cache commit is allowed when the response’s body is fully received.

    8. Add responsePromise to responsePromises.

  5. Let p be the result of getting a promise to wait for all of responsePromises.

  6. Return the result of reacting to p with a fulfillment handler that, when called with argument responses, performs the following substeps:

    1. Let operations be an empty list.

    2. Let index be zero.

    3. For each response in responses:

      1. Let operation be a cache batch operation.

      2. Set operation’s type to "put".

      3. Set operation’s request to requestList[index].

      4. Set operation’s response to response.

      5. Append operation to operations.

      6. Increment index by one.

    4. Let realm be the context object's relevant realm.

    5. Let cacheJobPromise be a new promise.

    6. Run the following substeps in parallel:

      1. Let errorData be null.

      2. Invoke Batch Cache Operations with operations. If this throws an exception, set errorData to the exception.

      3. Queue a task, on cacheJobPromise’s relevant settings object's responsible event loop using the DOM manipulation task source, to perform the following substeps:

        1. If errorData is null, resolve cacheJobPromise with undefined.

        2. Else, reject cacheJobPromise with a new exception with errorData and a user agent-defined message, in realm.

    7. Return cacheJobPromise.

5.4.5. put(request, response)

put(request, response) method must run these steps:

  1. Let r be null.

  2. If request is a Request object, then:

    1. Set r to request’s request.

    2. If r’s url's scheme is not one of "http" and "https", or r’s method is not `GET`, return a promise rejected with a TypeError.

  3. Else if request is a string, then:

    1. Set r to the associated request of the result of invoking the initial value of Request as constructor with request as its argument. If this throws an exception, return a promise rejected with that exception.

    2. If r’s url's scheme is not one of "http" and "https", return a promise rejected with a TypeError.

  4. If response’s associated response's status is 206, return a promise rejected with a TypeError.

  5. If response’s associated response's header list contains a header named `Vary`, then:

    1. Let fieldValues be the list containing the items corresponding to the Vary header’s field-values.

    2. For each fieldValue in fieldValues:

      1. If fieldValue matches "*", return a promise rejected with a TypeError.

  6. If response is disturbed or locked, return a promise rejected with a TypeError.

  7. Let clonedResponse be the result of cloning response’s associated response.

  8. If response’s body is non-null, run these substeps:

    1. Let dummyStream be an empty ReadableStream object.

    2. Set response’s body to a new body whose stream is dummyStream.

    3. Let reader be the result of getting a reader from dummyStream.

    4. Read all bytes from dummyStream with reader.

  9. Let operations be an empty list.

  10. Let operation be a cache batch operation.

  11. Set operation’s type to "put".

  12. Set operation’s request to r.

  13. Set operation’s response to clonedResponse.

  14. Append operation to operations.

  15. Let realm be the context object's relevant realm.

  16. Let cacheJobPromise be a new promise.

  17. Run the following substeps in parallel:

    1. Let errorData be null.

    2. Invoke Batch Cache Operations with operations. If this throws an exception, set errorData to the exception.

    3. Queue a task, on cacheJobPromise’s relevant settings object's responsible event loop using the DOM manipulation task source, to perform the following substeps:

      1. If errorData is null, resolve cacheJobPromise with undefined.

      2. Else, reject cacheJobPromise with a new exception with errorData and a user agent-defined message, in realm.

  18. Return cacheJobPromise.

5.4.6. delete(request, options)

delete(request, options) method must run these steps:

  1. Let r be null.

  2. If request is a Request object, then:

    1. Set r to request’s request.

    2. If r’s method is not `GET` and options.ignoreMethod is false, return a promise resolved with false.

  3. Else if request is a string, then:

    1. Set r to the associated request of the result of invoking the initial value of Request as constructor with request as its argument. If this throws an exception, return a promise rejected with that exception.

  4. Let operations be an empty list.

  5. Let operation be a cache batch operation.

  6. Set operation’s type to "delete".

  7. Set operation’s request to r.

  8. Set operation’s options to options.

  9. Append operation to operations.

  10. Let realm be the context object's relevant realm.

  11. Let cacheJobPromise be a new promise.

  12. Run the following substeps in parallel:

    1. Let errorData be null.

    2. Let requestResponses be the result of running Batch Cache Operations with operations. If this throws an exception, set errorData to the exception.

    3. Queue a task, on cacheJobPromise’s relevant settings object's responsible event loop using the DOM manipulation task source, to perform the following substeps:

      1. If errorData is null, then:

        1. If requestResponses is not empty, resolve cacheJobPromise with true.

        2. Else, resolve cacheJobPromise with false.

      2. Else, reject cacheJobPromise with a new exception with errorData and a user agent-defined message, in realm.

  13. Return cacheJobPromise.

5.4.7. keys(request, options)

keys(request, options) method must run these steps:

  1. Let r be null.

  2. If the optional argument request is not omitted, then:

    1. If request is a Request object, then:

      1. Set r to request’s request.

      2. If r’s method is not `GET` and options.ignoreMethod is false, return a promise resolved with an empty array.

    2. Else if request is a string, then:

      1. Set r to the associated request of the result of invoking the initial value of Request as constructor with request as its argument. If this throws an exception, return a promise rejected with that exception.

  3. Let realm be the context object's relevant realm.

  4. Let promise be a new promise.

  5. Run these substeps in parallel:

    1. Let requests be an empty list.

    2. If the optional argument request is omitted, then:

      1. For each requestResponse of the relevant request response list:

        1. Add requestResponse’s request to requests.

    3. Else:

      1. Let requestResponses be the result of running Query Cache with r and options.

      2. For each requestResponse of requestResponses:

        1. Add requestResponse’s request to requests.

    4. Queue a task, on promise’s relevant settings object's responsible event loop using the DOM manipulation task source, to perform the following steps:

      1. Let requestList be a list.

      2. For each request of requests:

        1. Add a new Request object associated with request and a new associated Headers object whose guard is "immutable" to requestList.

      3. Resolve promise with a frozen array created from requestList, in realm.

  6. Return promise.

5.5. CacheStorage

[SecureContext, Exposed=(Window,Worker)]
interface CacheStorage {
  [NewObject] Promise<any> match(RequestInfo request, optional MultiCacheQueryOptions options = {});
  [NewObject] Promise<boolean> has(DOMString cacheName);
  [NewObject] Promise<Cache> open(DOMString cacheName);
  [NewObject] Promise<boolean> delete(DOMString cacheName);
  [NewObject] Promise<sequence<DOMString>> keys();
};

dictionary MultiCacheQueryOptions : CacheQueryOptions {
  DOMString cacheName;
};

Note: CacheStorage interface is designed to largely conform to ECMAScript 6 Map objects but entirely async, and with additional convenience methods. The methods, clear, forEach, entries and values, are intentionally excluded from the scope of the first version resorting to the ongoing discussion about the async iteration by TC39.

The user agent must create a CacheStorage object when a Window object or a WorkerGlobalScope object is created and associate it with that global object.

A CacheStorage object represents a name to cache map of its associated global object's environment settings object’s origin. Multiple separate objects implementing the CacheStorage interface across documents and workers can all be associated with the same name to cache map simultaneously.

5.5.1. match(request, options)

match(request, options) method must run these steps:

  1. If options.cacheName is present, then:

    1. Return a new promise promise and run the following substeps in parallel:

      1. For each cacheNamecache of the relevant name to cache map:

        1. If options.cacheName matches cacheName, then:

          1. Resolve promise with the result of running the algorithm specified in match(request, options) method of Cache interface with request and options (providing cache as thisArgument to the [[Call]] internal method of match(request, options).)

          2. Abort these steps.

      2. Resolve promise with undefined.

  2. Else:

    1. Let promise be a promise resolved with undefined.

    2. For each cacheNamecache of the relevant name to cache map:

      1. Set promise to the result of reacting to itself with a fulfillment handler that, when called with argument response, performs the following substeps:

        1. If response is not undefined, return response.

        2. Return the result of running the algorithm specified in match(request, options) method of Cache interface with request and options as the arguments (providing cache as thisArgument to the [[Call]] internal method of match(request, options).)

    3. Return promise.

5.5.2. has(cacheName)

has(cacheName) method must run these steps:

  1. Let promise be a new promise.

  2. Run the following substeps in parallel:

    1. For each keyvalue of the relevant name to cache map:

      1. If cacheName matches key, resolve promise with true and abort these steps.

    2. Resolve promise with false.

  3. Return promise.

5.5.3. open(cacheName)

open(cacheName) method must run these steps:

  1. Let promise be a new promise.

  2. Run the following substeps in parallel:

    1. For each keyvalue of the relevant name to cache map:

      1. If cacheName matches key, then:

        1. Resolve promise with a new Cache object that represents value.

        2. Abort these steps.

    2. Let cache be a new request response list.

    3. Set the relevant name to cache map[cacheName] to cache. If this cache write operation failed due to exceeding the granted quota limit, reject promise with a "QuotaExceededError" DOMException and abort these steps.

    4. Resolve promise with a new Cache object that represents cache.

  3. Return promise.

5.5.4. delete(cacheName)

delete(cacheName) method must run these steps:

  1. Let promise be the result of running the algorithm specified in has(cacheName) method with cacheName.

  2. Return the result of reacting to promise with a fulfillment handler that, when called with argument cacheExists, performs the following substeps:

    1. If cacheExists is false, then:

      1. Return false.

    2. Let cacheJobPromise be a new promise.

    3. Run the following substeps in parallel:

      1. Remove the relevant name to cache map[cacheName].

      2. Resolve cacheJobPromise with true.

      Note: After this step, the existing DOM objects (i.e. the currently referenced Cache, Request, and Response objects) should remain functional.

    4. Return cacheJobPromise.

5.5.5. keys()

keys() method must run these steps:

  1. Let promise be a new promise.

  2. Run the following substeps in parallel:

    1. Let cacheKeys be the result of getting the keys of the relevant name to cache map.

      Note: The items in the result ordered set are in the order that their corresponding entry was added to the name to cache map.

    2. Resolve promise with cacheKeys.

  3. Return promise.

6. Security Considerations

6.1. Secure Context

Service workers must execute in secure contexts. Service worker clients must also be secure contexts to register a service worker registration, to get access to the service worker registrations and the service workers, to do messaging with the service workers, and to be manipulated by the service workers.

Note: This effectively means that service workers and their service worker clients need to be hosted over HTTPS. A user agent can allow localhost (see the requirements), 127.0.0.0/8, and ::1/128 for development purposes. The primary reason for this restriction is to protect users from the risks associated with insecure contexts.

6.2. Content Security Policy

Whenever a user agent invokes the Run Service Worker algorithm with a service worker serviceWorker:

  • If serviceWorker’s script resource was delivered with a Content-Security-Policy HTTP header containing the value policy, the user agent must enforce policy for serviceWorker.

  • If serviceWorker’s script resource was delivered with a Content-Security-Policy-Report-Only HTTP header containing the value policy, the user agent must monitor policy for serviceWorker.

The primary reason for this restriction is to mitigate a broad class of content injection vulnerabilities, such as cross-site scripting (XSS).

6.3. Origin Relativity

6.3.1. Origin restriction

This section is non-normative.

A service worker executes in the registering service worker client's origin. One of the advanced concerns that major applications would encounter is whether they can be hosted from a CDN. By definition, these are servers in other places, often on other origins. Therefore, service workers cannot be hosted on CDNs. But they can include resources via importScripts(). The reason for this restriction is that service workers create the opportunity for a bad actor to turn a bad day into a bad eternity.

6.3.2. importScripts(urls)

When the importScripts(urls) method is called on a ServiceWorkerGlobalScope object, the user agent must import scripts into worker global scope, given this ServiceWorkerGlobalScope object and urls, and with the following steps to perform the fetch given the request request:

  1. Let serviceWorker be request’s client's global object's service worker.

  2. If serviceWorker’s script resource map[request’s url] exists, return the entry's value.

  3. If serviceWorker’s state is not "parsed" or "installing" return a network error.

  4. Let registration be serviceWorker’s containing service worker registration.

  5. Set request’s service-workers mode to "none".

  6. Set request’s cache mode to "no-cache" if any of the following are true:

  7. Let response be the result of fetching request.

  8. Set response to response’s unsafe response.

  9. If response’s cache state is not "local", set registration’s last update check time to the current time.

  10. Extract a MIME type from the response’s header list. If this MIME type (ignoring parameters) is not a JavaScript MIME type, return a network error.

  11. If response’s type is not "error", and response’s status is an ok status, then:

    1. Set serviceWorker’s script resource map[request’s url] to response.

    2. Set serviceWorker’s classic scripts imported flag.

  12. Return response.

6.4. Cross-Origin Resources and CORS

This section is non-normative.

Applications tend to cache items that come from a CDN or other origin. It is possible to request many of them directly using

Index

Terms defined by this specification

Terms defined by reference

  • [csp-3] defines the following terms:
    • enforced
    • monitored
  • [DOM] defines the following terms:
    • Document
    • Event
    • EventInit
    • EventTarget
    • cancelable
    • canceled flag
    • context object
    • creating an event
    • dispatch
    • dispatch flag
    • document
    • event
    • event listener
    • fire an event
    • isTrusted
    • stop immediate propagation flag
    • stop propagation flag
    • type
  • [ECMASCRIPT] defines the following terms:
    • detacharraybuffer
    • execution context
    • initializehostdefinedrealm
    • map objects
    • promise
  • [FETCH] defines the following terms:
    • "report"
    • Headers
    • ReadableStream
    • Request
    • RequestInfo
    • Response
    • aborted flag
    • basic filtered response
    • body (for response)
    • cache mode
    • cache state
    • cancel
    • client
    • clone
    • closed
    • combine
    • construct a readablestream object
    • contains
    • cors filtered response
    • destination
    • disturbed
    • empty
    • enqueue
    • errored
    • extract a mime type
    • extracting header list values
    • fetch
    • fetch(input, init)
    • filtered response
    • get a reader
    • guard
    • header
    • header list (for response)
    • http fetch
    • https state
    • https state value
    • initiator
    • locked
    • method
    • name
    • navigation request
    • network error
    • non-subresource request
    • ok status
    • opaque filtered response
    • origin
    • parser metadata
    • potential-navigation-or-subresource request
    • process response
    • process response end-of-body
    • read a chunk
    • read all bytes
    • redirect mode
    • request (for Request)
    • reserved client
    • response (for Response)
    • service-workers mode
    • status
    • stream
    • subresource request
    • synchronous flag
    • terminated
    • type
    • url
    • use-url-credentials flag
    • value
  • [FileAPI] defines the following terms:
    • blob url
    • environment
  • [HTML] defines the following terms:
    • AbstractWorker
    • DOMContentLoaded
    • DedicatedWorkerGlobalScope
    • EventHandler
    • Location
    • MessageEvent
    • MessagePort
    • Navigator
    • SharedWorkerGlobalScope
    • StructuredDeserializeWithTransfer
    • StructuredSerializeWithTransfer
    • Window
    • WindowOrWorkerGlobalScope
    • Worker
    • WorkerGlobalScope
    • WorkerLocation
    • WorkerNavigator
    • WorkerType
    • active document
    • active service worker
    • ancestor origins list
    • api base url
    • api url character encoding
    • application cache
    • auxiliary browsing context
    • base url
    • browsing context
    • classic script
    • closing
    • creation url
    • current global object
    • data
    • discard
    • discard a document
    • dom manipulation task source
    • environment discarding steps
    • environment settings object
    • event handler
    • event handler event type
    • event handler idl attribute
    • event loop
    • exceptions enabled flag
    • execution ready flag
    • fetch a classic worker script
    • fetch a module worker script graph
    • focusing steps
    • global object (for environment settings object)
    • has focus steps
    • https state (for environment settings object)
    • id
    • iframe
    • import scripts into worker global scope
    • importScripts(urls)
    • in parallel
    • incumbent settings object
    • is top-level
    • list of active timers
    • message
    • module script
    • navigate
    • nested browsing context
    • opaque origin
    • origin (for environment settings object)
    • owner set
    • perform the fetch
    • ports
    • queue a microtask
    • queue a task
    • realm (for global object)
    • realm execution context
    • referrer policy (for environment settings object)
    • relevant global object
    • relevant realm
    • relevant settings object
    • replacement enabled
    • responsible document
    • responsible event loop
    • run a classic script
    • run a module script
    • run a worker
    • same origin
    • sandbox
    • script
    • serialization of an origin
    • shared worker
    • source
    • source browsing context
    • target browsing context
    • task
    • task queues
    • task source
    • top-level browsing context
    • triggered by user activation
    • type
    • unload a document
    • unsafe response
    • url
    • user interaction task source
    • web worker
  • [INFRA] defines the following terms:
    • append (for set)
    • ascii case-insensitive
    • break
    • contain
    • continue
    • dequeue
    • enqueue
    • entry
    • exist
    • for each (for map)
    • get the keys
    • is not empty
    • item
    • key
    • list
    • map
    • ordered map
    • ordered set
    • pair
    • queue
    • remove (for map)
    • set
    • struct
    • value
  • [MIMESNIFF] defines the following terms:
    • javascript mime type
  • [page-visibility] defines the following terms:
    • VisibilityState
    • visibilityState
  • [push] defines the following terms:
    • push
  • [referrer-policy] defines the following terms:
    • referrer policy
  • [rfc7230] defines the following terms:
    • field-value
  • [rfc7231] defines the following terms:
    • vary
  • [secure-contexts] defines the following terms:
    • potentially trustworthy origin
    • potentially trustworthy url
    • secure contexts
  • [STREAMS] defines the following terms:
    • chunk
  • [URL] defines the following terms:
    • equal
    • fragment
    • origin
    • path
    • query
    • scheme
    • url
    • url parser
    • url serializer
  • [webappsec-referrer-policy] defines the following terms:
    • parse a referrer policy from a referrer-policy header
  • [WebIDL] defines the following terms:
    • AbortError
    • DOMException
    • DOMString
    • Exposed
    • Global
    • InvalidAccessError
    • InvalidStateError
    • NewObject
    • QuotaExceededError
    • SameObject
    • SecureContext
    • SecurityError
    • USVString
    • a new promise
    • a promise rejected with
    • a promise resolved with
    • boolean
    • create a frozen array
    • created
    • exception
    • frozen array type
    • getting a promise to wait for all
    • message
    • object
    • partial interface
    • present
    • reacting
    • throw
    • upon fulfillment
    • upon rejection

References

Normative References

[CSP-3]
Content Security Policy Level 3 URL: https://www.w3.org/TR/CSP3/
[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
ECMAScript Language Specification. URL: https://tc39.github.io/ecma262/
[FETCH]
Anne van Kesteren. Fetch Standard. Living Standard. URL: https://fetch.spec.whatwg.org/
[FileAPI]
Marijn Kruisselbrink; Arun Ranganathan. File API. 11 September 2019. WD. URL: https://www.w3.org/TR/FileAPI/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[MIMESNIFF]
Gordon P. Hemsley. MIME Sniffing Standard. Living Standard. URL: https://mimesniff.spec.whatwg.org/
[PAGE-VISIBILITY]
Jatinder Mann; Arvind Jain. Page Visibility (Second Edition). 29 October 2013. REC. URL: https://www.w3.org/TR/page-visibility/
[REFERRER-POLICY]
Jochen Eisinger; Emily Stark. Referrer Policy. 26 January 2017. CR. URL: https://www.w3.org/TR/referrer-policy/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[RFC5234]
D. Crocker, Ed.; P. Overell. Augmented BNF for Syntax Specifications: ABNF. January 2008. Internet Standard. URL: https://tools.ietf.org/html/rfc5234
[RFC7230]
R. Fielding, Ed.; J. Reschke, Ed.. Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing. June 2014. Proposed Standard. URL: https://httpwg.org/specs/rfc7230.html
[RFC7231]
R. Fielding, Ed.; J. Reschke, Ed.. Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content. June 2014. Proposed Standard. URL: https://httpwg.org/specs/rfc7231.html
[SECURE-CONTEXTS]
Mike West. Secure Contexts. 15 September 2016. CR. URL: https://www.w3.org/TR/secure-contexts/
[STREAMS]
Adam Rice; Domenic Denicola; 吉野剛史 (Takeshi Yoshino). Streams Standard. Living Standard. URL: https://streams.spec.whatwg.org/
[URL]
Anne van Kesteren. URL Standard. Living Standard. URL: https://url.spec.whatwg.org/
[WebIDL]
Boris Zbarsky. Web IDL. 15 December 2016. ED. URL: https://heycam.github.io/webidl/

Informative References

[UNSANCTIONED-TRACKING]
Unsanctioned Web Tracking. 17 July 2015. Finding of the W3C TAG. URL: https://www.w3.org/2001/tag/doc/unsanctioned-tracking/

IDL Index

[SecureContext, Exposed=(Window,Worker)]
interface ServiceWorker : EventTarget {
  readonly attribute USVString scriptURL;
  readonly attribute ServiceWorkerState state;
  void postMessage(any message, optional sequence<object> transfer = []);

  // event
  attribute EventHandler onstatechange;
};
ServiceWorker includes AbstractWorker;

enum ServiceWorkerState {
  "installing",
  "installed",
  "activating",
  "activated",
  "redundant"
};

[SecureContext, Exposed=(Window,Worker)]
interface ServiceWorkerRegistration : EventTarget {
  readonly attribute ServiceWorker? installing;
  readonly attribute ServiceWorker? waiting;
  readonly attribute ServiceWorker? active;

  readonly attribute USVString scope;
  readonly attribute ServiceWorkerUpdateViaCache updateViaCache;

  [NewObject] Promise<void> update();
  [NewObject] Promise<boolean> unregister();

  // event
  attribute EventHandler onupdatefound;
};

enum ServiceWorkerUpdateViaCache {
  "imports",
  "all",
  "none"
};

partial interface Navigator {
  [SecureContext, SameObject] readonly attribute ServiceWorkerContainer serviceWorker;
};

partial interface WorkerNavigator {
  [SecureContext, SameObject] readonly attribute ServiceWorkerContainer serviceWorker;
};

[SecureContext, Exposed=(Window,Worker)]
interface ServiceWorkerContainer : EventTarget {
  readonly attribute ServiceWorker? controller;
  readonly attribute Promise<ServiceWorkerRegistration> ready;

  [NewObject] Promise<ServiceWorkerRegistration> register(USVString scriptURL, optional RegistrationOptions options = {});

  [NewObject] Promise<any> getRegistration(optional USVString clientURL = "");
  [NewObject] Promise<FrozenArray<ServiceWorkerRegistration>> getRegistrations();

  void startMessages();


  // events
  attribute EventHandler oncontrollerchange;
  attribute EventHandler onmessage; // event.source of message events is ServiceWorker object
  attribute EventHandler onmessageerror;
};

dictionary RegistrationOptions {
  USVString scope;
  WorkerType type = "classic";
  ServiceWorkerUpdateViaCache updateViaCache = "imports";
};

[Global=(Worker,ServiceWorker), Exposed=ServiceWorker]
interface ServiceWorkerGlobalScope : WorkerGlobalScope {
  [SameObject] readonly attribute Clients clients;
  [SameObject] readonly attribute ServiceWorkerRegistration registration;

  [NewObject] Promise<void> skipWaiting();

  attribute EventHandler oninstall;
  attribute EventHandler onactivate;
  attribute EventHandler onfetch;

  attribute EventHandler onmessage;
  attribute EventHandler onmessageerror;
};

[Exposed=ServiceWorker]
interface Client {
  readonly attribute USVString url;
  readonly attribute FrameType frameType;
  readonly attribute DOMString id;
  readonly attribute ClientType type;
  void postMessage(any message, optional sequence<object> transfer = []);
};

[Exposed=ServiceWorker]
interface WindowClient : Client {
  readonly attribute VisibilityState visibilityState;
  readonly attribute boolean focused;
  [SameObject] readonly attribute FrozenArray<USVString> ancestorOrigins;
  [NewObject] Promise<WindowClient> focus();
  [NewObject] Promise<WindowClient?> navigate(USVString url);
};

enum FrameType {
  "auxiliary",
  "top-level",
  "nested",
  "none"
};

[Exposed=ServiceWorker]
interface Clients {
  // The objects returned will be new instances every time
  [NewObject] Promise<any> get(DOMString id);
  [NewObject] Promise<FrozenArray<Client>> matchAll(optional ClientQueryOptions options = {});
  [NewObject] Promise<WindowClient?> openWindow(USVString url);
  [NewObject] Promise<void> claim();
};

dictionary ClientQueryOptions {
  boolean includeUncontrolled = false;
  ClientType type = "window";
};

enum ClientType {
  "window",
  "worker",
  "sharedworker",
  "all"
};

[Exposed=ServiceWorker]
interface ExtendableEvent : Event {
  constructor(DOMString type, optional ExtendableEventInit eventInitDict = {});
  void waitUntil(Promise<any> f);
};

dictionary ExtendableEventInit : EventInit {
  // Defined for the forward compatibility across the derived events
};

[Exposed=ServiceWorker]
interface FetchEvent : ExtendableEvent {
  constructor(DOMString type, FetchEventInit eventInitDict);
  [SameObject] readonly attribute Request request;
  readonly attribute DOMString clientId;

  void respondWith(Promise<Response> r);
};

dictionary FetchEventInit : ExtendableEventInit {
  required Request request;
  DOMString clientId = "";
};

[Exposed=ServiceWorker]
interface ExtendableMessageEvent : ExtendableEvent {
  constructor(DOMString type, optional ExtendableMessageEventInit eventInitDict = {});
  readonly attribute any data;
  readonly attribute USVString origin;
  readonly attribute DOMString lastEventId;
  [SameObject] readonly attribute (Client or ServiceWorker or MessagePort)? source;
  readonly attribute FrozenArray<MessagePort> ports;
};

dictionary ExtendableMessageEventInit : ExtendableEventInit {
  any data = null;
  USVString origin = "";
  DOMString lastEventId = "";
  (Client or ServiceWorker or MessagePort)? source = null;
  sequence<MessagePort> ports = [];
};

partial interface WindowOrWorkerGlobalScope {
  [SecureContext, SameObject] readonly attribute CacheStorage caches;
};

[SecureContext, Exposed=(Window,Worker)]
interface Cache {
  [NewObject] Promise<any> match(RequestInfo request, optional CacheQueryOptions options = {});
  [NewObject] Promise<FrozenArray<Response>> matchAll(optional RequestInfo request, optional CacheQueryOptions options = {});
  [NewObject] Promise<void> add(RequestInfo request);
  [NewObject] Promise<void> addAll(sequence<RequestInfo> requests);
  [NewObject] Promise<void> put(RequestInfo request, Response response);
  [NewObject] Promise<boolean> delete(RequestInfo request, optional CacheQueryOptions options = {});
  [NewObject] Promise<FrozenArray<Request>> keys(optional RequestInfo request, optional CacheQueryOptions options = {});
};

dictionary CacheQueryOptions {
  boolean ignoreSearch = false;
  boolean ignoreMethod = false;
  boolean ignoreVary = false;
};

[SecureContext, Exposed=(Window,Worker)]
interface CacheStorage {
  [NewObject] Promise<any> match(RequestInfo request, optional MultiCacheQueryOptions options = {});
  [NewObject] Promise<boolean> has(DOMString cacheName);
  [NewObject] Promise<Cache> open(DOMString cacheName);
  [NewObject] Promise<boolean> delete(DOMString cacheName);
  [NewObject] Promise<sequence<DOMString>> keys();
};

dictionary MultiCacheQueryOptions : CacheQueryOptions {
  DOMString cacheName;
};