1 of 16

Purpose of this document

To document the scope and known caveats of Service Worker in Chrome M40.

Publicly shared

2 of 16

API caveats

  • getAll (in ServiceWorkerClients) does not support the option parameter yet
  • ServiceWorkerClient’s id attribute is obsolete, please do not use it (crbug.com/407944).
  • Events in ServiceWorkerGlobalScope have their source set to null instead of the relevant instance of ServiceWorkerClient (crbug.com/403693)
  • Creating a Fetch Response from formData is currently unsupported (on the other hand, creating a Fetch Request from formData is supported).
  • Creating a Fetch Response or a Fetch Request from URLSearchParams isn’t supported yet.
  • Fetch and associated interfaces/apis are only exposed to Service Workers at this time (crbug.com/408041).
  • Fetch does not support redirections (crbug.com/402389)
  • Service Worker can’t catch OPTIONS request (crbug.com/434660)
  • When a Service Worker responds with a different origin, that new origin is incorrectly used as the base URL for that response (crbug.com/433743)

See this document for the Service Worker Cache APIs’s Scope and Caveats.

Development caveats

  • Sometime, getting an updated Service Worker to be used can be tricky. See our getting started guide for a recommended development flow.
  • FIXED in M40 When the inspector reconnects to a Service Worker, expressions in the console seems to be missing globals from the Service Worker etc.. (crbug.com/420005)

Implementation caveats

  • FIXED in M40 Currently, assets that may be controlled by a Service Worker script are always loaded from the Disk cache which may impact performance. Eventually, Service Worker controlled pages should be able to take advantage of in-memory caching (crbug.com/423219).

Known caveats

3 of 16

[Exposed=(Window,ServiceWorker)]

interface ServiceWorker : Worker {

readonly attribute ScalarValueString scriptURL;

readonly attribute ServiceWorkerState state;

// event

attribute EventHandler onstatechange;

// terminate() method inherited from Worker should not be accessible.

};

enum ServiceWorkerState {

"installing",

"installed",

"activating",

"activated",

"redundant"

};

4 of 16

partial interface Navigator {

readonly attribute ServiceWorkerContainer serviceWorker;

};

5 of 16

[Exposed=Window]

interface ServiceWorkerContainer : EventTarget {

[Unforgeable] readonly attribute ServiceWorker? controller;

readonly attribute Promise<ServiceWorkerRegistration> ready;

Promise<ServiceWorkerRegistration> register(ScalarValueString scriptURL, optional

RegistrationOptions options);

Promise<ServiceWorkerRegistration> getRegistration(optional ScalarValueString documentURL = "");

};

dictionary RegistrationOptionList {

ScalarValueString scope = "/";

};

6 of 16

[Exposed=Window]

interface ServiceWorkerRegistration : EventTarget {

[Unforgeable] readonly attribute ServiceWorker? installing;

[Unforgeable] readonly attribute ServiceWorker? waiting;

[Unforgeable] readonly attribute ServiceWorker? active;

readonly attribute ScalarValueString scope;

Promise<any> unregister();

// event

attribute EventHandler onupdatefound;

};

7 of 16

[Global=(Worker,ServiceWorker), Exposed=ServiceWorker]

interface ServiceWorkerGlobalScope : WorkerGlobalScope {

// A container for a list of window objects, identifiable by ID, that

// correspond to windows (or workers) that are "controlled" by this SW

readonly attribute ServiceWorkerClients clients;

[Unforgeable] readonly attribute ScalarValueString scope;

// fetch(input, init) method is defined in Fetch

Promise<Response> fetch(RequestInfo input, optional RequestInit init);

attribute EventHandler oninstall;

attribute EventHandler onactivate;

attribute EventHandler onfetch;

attribute EventHandler onmessage;

// The event.source of these MessageEvents are instances of Client

// close() method inherited from WorkerGlobalScope should not be accessible.

};

8 of 16

[Exposed=ServiceWorker]

interface ServiceWorkerClient {

readonly attribute unsigned long id; // id obsolete, do not rely on it (crbug.com/407944)

void postMessage(any message, optional sequence<Transferable> transfer);

};

9 of 16

[Exposed=ServiceWorker]

interface ExtendableEvent : Event {

Promise<any> waitUntil(Promise<any> f);

};

10 of 16

[Exposed=ServiceWorker]

interface ServiceWorkerClients {

// The objects returned will be new instances every time

Promise<sequence<ServiceWorkerClient>?> getAll(optional ServiceWorkerClientQueryOptions options);

};

dictionary ServiceWorkerClientQueryOptions {

boolean includeUncontrolled;

};

11 of 16

[Exposed=ServiceWorker]

interface InstallEvent : ExtendableEvent {

};

12 of 16

[Exposed=ServiceWorker]

interface FetchEvent : Event {

readonly attribute Request request;

readonly attribute boolean isReload;

void respondWith(Promise<Response> r);

};

13 of 16

[NoInterfaceObject, Exposed=(ServiceWorker)]

interface Body {

Promise<ArrayBuffer> arrayBuffer();

Promise<Blob> blob();

Promise<JSON> json();

Promise<ScalarValueString> text();

};

typedef (ArrayBuffer or ArrayBufferView or Blob or FormData or ScalarValueString) BodyInit;

14 of 16

typedef (Request or ScalarValueString) RequestInfo;��[Constructor(RequestInfo input, optional RequestInit init), Exposed=(ServiceWorker)]�interface Request {� readonly attribute ByteString method;� readonly attribute ScalarValueString url;� readonly attribute Headers headers;� readonly attribute DOMString referrer;� readonly attribute RequestMode mode;� readonly attribute RequestCredentials credentials;

Request clone();�};

Request implements Body;

dictionary RequestInit {� ByteString method;� HeadersInit headers;� BodyInit body;� RequestMode mode;� RequestCredentials credentials;�};�

�enum RequestMode { "same-origin", "no-cors", "cors" };�enum RequestCredentials { "omit", "same-origin", "include" };

15 of 16

[Constructor(optional BodyInit body, optional ResponseInit init), Exposed=(ServiceWorker)]�interface Response {� readonly attribute ResponseType type;� readonly attribute ScalarValueString url;� readonly attribute unsigned short status;� readonly attribute ByteString statusText;� readonly attribute Headers headers;�

Response clone();

};

Response implements Body;

dictionary ResponseInit {� unsigned short status = 200;� ByteString statusText = "OK";� HeadersInit headers;�};�

enum ResponseType { "basic", "cors", "default", "error", "opaque" };

16 of 16

[Constructor(optional HeadersInit init), Exposed=(ServiceWorker)]

interface Headers {

void append(ByteString name, ByteString value);

void delete(ByteString name);

ByteString? get(ByteString name);

sequence<ByteString> getAll(ByteString name);

boolean has(ByteString name);

void set(ByteString name, ByteString value);

};

typedef (Headers or sequence<sequence<ByteString>> or OpenEndedDictionary<ByteString>) HeadersInit;