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 id (an opaque string), which uniquely identifies itself during the lifetime of its containing service worker registration .
A
service
worker
has
an
associated
global
object
(a
ServiceWorkerGlobalScope
object
or
null).
A
service
worker
is
dispatched
a
set
of
lifecycle
events
,
install
and
activate
,
and
functional
events
including
fetch
.
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 imported scripts updated 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 list of foreign fetch scopes whose element type is a URL . It is initially empty.
A service worker has an associated list of foreign fetch origins whose element type is a URL . It is initially empty.
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.
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 has an associated use cache (a boolean). It is initially set to false.
A service worker registration has an associated uninstalling flag . It is initially unset.
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
has
an
associated
NavigationPreloadManager
object.
A service worker registration has an associated navigation preload enabled flag . It is initially unset.
A
service
worker
registration
has
an
associated
navigation
preload
header
value
,
which
is
a
byte
sequence
.
It
is
initially
set
to
`
true
`.
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
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
a
type
of
environment
or
environment
settings
object
.
A
service
worker
client
has
an
algorithm
defined
as
the
origin
that
returns
the
service
worker
client
's
creation
URL
’s
origin
if
the
service
worker
client
is
a
type
of
environment
,
and
the
service
worker
client
'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
service
worker
client
is
a
client
whose
global
object
is
a
ServiceWorkerGlobalScope
object.
A
worker
client
is
either
a
dedicated
worker
client
or
,
a
shared
worker
client
,
or
a
service
worker
client
.
2.4. Selection and Use
A
service
worker
client
independently
selects
and
uses
a
service
worker
registration
for
its
own
loading
and
its
subresources.
The
selection
of
a
service
worker
registration
,
upon
a
non-subresource
request
,
is
a
process
of
either
matching
a
service
worker
registration
from
scope
to
registration
map
or
inheriting
an
existing
service
worker
registration
from
its
parent
or
owner
context
depending
on
the
request’s
url
.
When
the
request’s
url
is
not
local
,
a
service
worker
client
matches
a
service
worker
registration
from
scope
to
registration
map
.
That
is,
the
service
worker
client
attempts
to
consult
a
service
worker
registration
whose
scope
url
matches
its
creation
URL
.
When
the
request’s
url
is
local
,
if
the
service
worker
client
's
responsible
browsing
context
is
a
nested
browsing
context
or
the
service
worker
client
is
a
worker
client
,
the
service
worker
client
inherits
the
service
worker
registration
from
its
parent
browsing
context
’s
environment
or
one
of
the
worker’s
Documents
'
environment,
respectively,
if
it
exists.
If
the
selection
was
successful,
the
selected
service
worker
registration
's
active
worker
starts
to
control
the
service
worker
client
.
Otherwise,
the
flow
returns
to
fetch
where
it
falls
back
to
the
default
behavior.
When
a
service
worker
client
is
controlled
by
an
active
worker
,
it
is
considered
that
the
service
worker
client
is
using
the
active
worker
’s
containing
service
worker
registration
.
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:
-
An installing worker does not persist but discarded. If the installing worker was the only service worker for the service worker registration , the service worker registration is discarded.
-
A waiting worker promotes to an active worker .
To attain this, the user agent must invoke Handle User Agent Shutdown when it terminates.
3. Client Context
// 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 >= []); // event
transfer attribute EventHandler onstatechange ; };ServiceWorker implements 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.
scriptURL
The
scriptURL
attribute
must
return
the
service
worker
's
serialized
script
url
.
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.2.
state
The
state
attribute
must
return
the
value
(in
ServiceWorkerState
enumeration)
to
which
it
was
last
set.
3.1.3.
postMessage(message,
transfer)
The
postMessage(
message
,
transfer
)
method
must
run
these
steps:
-
If the
state
attribute value of the context object is"redundant"
, throw an "InvalidStateError
" exception and abort these steps. -
Let serviceWorker be the service worker represented by the context object .
-
Invoke Run Service Worker algorithm with serviceWorker as the argument.
-
Let destination be the
ServiceWorkerGlobalScope
object associated with serviceWorker . -
Let targetRealm be destination ’s Realm .
-
Let incumbentSettings be the incumbent settings object , and incumbentGlobal its global object .
-
Let cloneRecord be StructuredCloneWithTransfer ( message , transfer , targetRealm ). If this throws an exception, rethrow that exception and abort these steps.
-
Let clonedMessage be cloneRecord .[[Clone]].
-
Let newPorts be a new frozen array consisting of all
MessagePort
objects in cloneRecord .[[TransferList]], if any, maintaining their relative order. -
Queue a task that runs the following steps:
-
Create an event e that uses the
ExtendableMessageEvent
interface, with the event typemessage
, which does not bubble and is not cancelable. -
Let the
data
attribute of e be initialized to clonedMessage . -
Let the
origin
attribute of e be initialized to the Unicode serialization of incumbentSettings ’s origin . -
If incumbentGlobal is a
ServiceWorkerGlobalScope
object, let thesource
attribute of e be initialized to a newServiceWorker
object that represents incumbentGlobal ’s service worker . -
Else if incumbentGlobal is a
Window
object, let thesource
attribute of e be initialized to a newWindowClient
object that represents incumbentGlobal ’s browsing context . -
Else, let it be initialized to a new
Client
object that represents the worker associated with incumbentGlobal . -
Let the
ports
attribute of e be initialized to newPorts . -
Dispatch e at destination .
The task must use the DOM manipulation task source .
-
3.1.4. 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 NavigationPreloadManager navigationPreload ;readonly attribute USVString scope ;readonly attribute boolean useCache ; [NewObject ]Promise <void >update (); [NewObject ]Promise <boolean >unregister (); // eventattribute EventHandler onupdatefound ; };
A
ServiceWorkerRegistration
object
represents
a
service
worker
registration
.
Each
ServiceWorkerRegistration
object
is
associated
with
a
service
worker
registration
(a
service
worker
registration
).
Multiple
separate
objects
implementing
the
ServiceWorkerRegistration
interface
across
documents
and
workers
can
all
be
associated
with
the
same
service
worker
registration
simultaneously.
3.2.1.
installing
installing
attribute
must
return
the
value
to
which
it
was
last
set.
Note:
The
ServiceWorker
objects
returned
from
this
attribute
getter
that
represent
the
same
service
worker
are
the
same
objects.
3.2.2.
waiting
waiting
attribute
must
return
the
value
to
which
it
was
last
set.
Note:
The
ServiceWorker
objects
returned
from
this
attribute
getter
that
represent
the
same
service
worker
are
the
same
objects.
3.2.3.
active
active
attribute
must
return
the
value
to
which
it
was
last
set.
Note:
The
ServiceWorker
objects
returned
from
this
attribute
getter
that
represent
the
same
service
worker
are
the
same
objects.
3.2.4.
navigationPreload
The
navigationPreload
attribute
must
return
service
worker
registration
's
NavigationPreloadManager
object.
3.2.5.
scope
The
scope
attribute
must
return
service
worker
registration
's
serialized
scope
url
.
registration.scope
,
obtained
from
navigator.serviceWorker.ready.then(registration
=>
console.log(registration.scope))
for
example,
will
be
"
https://example.com/
".
3.2.6.
useCache
The
useCache
attribute
must
return
service
worker
registration
's
use
cache
.
3.2.7.
update()
update()
method
must
run
these
steps:
-
Let p be a promise .
-
Let registration be the service worker registration .
-
Let newestWorker be the result of running Get Newest Worker algorithm passing registration as its argument.
-
If newestWorker is null, reject p with an "
InvalidStateError
" exception and abort these steps. -
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 , reject p with an "InvalidStateError
" exception and abort these steps. -
Let job be the result of running Create Job with update , registration ’s scope url , newestWorker ’s script url , p , and the context object ’s relevant settings object .
-
Set job ’s worker type to newestWorker ’s type .
-
Invoke Schedule Job with job .
-
Return p .
3.2.8.
unregister()
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:
-
Let p be a promise .
-
Let job be the result of running Create Job with unregister , the scope url of the service worker registration , null, p , and the context object ’s relevant settings object .
-
Invoke Schedule Job with job .
-
Return p .
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
|
3.3.
navigator.serviceWorker
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 <sequence <ServiceWorkerRegistration >>getRegistrations ();void startMessages (); // eventsattribute EventHandler oncontrollerchange ;attribute EventHandler onmessage ; // event.source of message events is ServiceWorker object };
dictionary {
RegistrationOptions USVString ;
scope WorkerType = "classic";
type boolean =
useCache false ; };
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
.
3.4.1.
controller
controller
attribute
must
run
these
steps:
-
Let client be the context object ’s
service workerclient . -
Return the
ServiceWorker
object that represents client ’s active service worker .
Note:
navigator.serviceWorker.controller
returns
null
if
the
request
is
a
force
refresh
(shift+refresh).
The
ServiceWorker
objects
returned
from
this
attribute
getter
that
represent
the
same
service
worker
are
the
same
objects.
3.4.2.
ready
ready
attribute
must
run
these
steps:
-
If the context object ’s ready promise is settled, return the context object ’s ready promise .
-
Let client be the context object ’s
service workerclient . -
Let registration be null.
-
Let clientURL be client ’s creation URL .
-
Run the following substeps in parallel :
-
CheckRegistration : If the result of running Match Service Worker Registration algorithm with clientURL as its argument is not null, then:
-
Set registration to the result value.
-
-
Else:
-
Wait until scope to registration map has a new entry.
-
Jump to the step labeled CheckRegistration .
-
-
If registration ’s active worker is null, wait until registration ’s active worker changes.
Note: Implementers should consider this condition is met when the corresponding registration request gets to the step 6 of Activate algorithm.
-
Resolve context object ’s ready promise with the
ServiceWorkerRegistration
object which represents registration .
-
-
Return context object ’s ready promise .
Note:
When
the
ready
attribute
is
accessed,
the
returned
promise
will
never
reject.
Instead,
it
waits
until
the
promise
resolves
with
a
service
worker
registration
that
has
an
active
worker
.
3.4.3.
register(scriptURL,
options)
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:
-
Let p be a promise .
-
Let client be the context object ’s
service workerclient . -
Let scriptURL be the result of parsing scriptURL with the context object ’s relevant settings object ’s API base URL .
-
Let scopeURL be null.
-
If options .
scope
is present , set scopeURL to the result of parsing options .scope
with the context object ’s relevant settings object ’s API base URL . -
Invoke Start Register with scopeURL , scriptURL , p , client , client ’s creation URL , options .
type
, and options .useCache
. -
Return p .
3.4.4.
getRegistration(clientURL)
getRegistration(
clientURL
)
method
must
run
these
steps:
-
Let client be the context object ’s
service workerclient . -
Let clientURL be the result of parsing clientURL with the context object ’s relevant settings object ’s API base URL .
-
If clientURL is failure, return a promise rejected with a
TypeError
. -
If the origin of clientURL is not client ’s origin , return a promise rejected with a "
SecurityError
" exception. -
Let promise be a new promise .
-
Run the following substeps in parallel :
-
Let registration be the result of running Match Service Worker Registration algorithm with clientURL as its argument.
-
If registration is not null, then:
-
Resolve promise with the
ServiceWorkerRegistration
object which represents registration .
-
-
Else:
-
Resolve promise with undefined.
-
-
-
Return promise .
3.4.5.
getRegistrations()
getRegistrations()
method
must
run
these
steps:
-
Let client be the context object ’s
service workerclient . -
Let promise be a new promise .
-
Run the following substeps in parallel :
-
Let array be an empty array.
-
For each key → value of scope to registration map :
-
If the origin of the result of parsing key is the same as client ’s origin , and value ’s uninstalling flag is unset, add the
ServiceWorkerRegistration
object associated with value to the array .
-
-
Resolve promise with array .
-
-
Return promise .
3.4.6.
startMessages()
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
|
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
navigator.serviceWorker.controller
immediately
reflects
the
active
worker
as
the
service
worker
that
controls
the
|
3.6.
NavigationPreloadManager
[SecureContext ,Exposed =(Window ,Worker )]interface {
NavigationPreloadManager Promise <void >enable ();Promise <void >disable ();Promise <void >setHeaderValue (ByteString );
value Promise <NavigationPreloadState >getState (); };dictionary {
NavigationPreloadState boolean =
enabled false ;ByteString ; };
headerValue
3.6.1.
enable()
The
enable()
method,
when
invoked,
must
return
a
new
promise
promise
and
run
the
following
steps
in
parallel
:
-
Let registration be the context object 's associated service worker registration .
-
If registration ’s active worker is null, reject promise with an "
InvalidStateError
" exception, and abort these steps. -
Set registration ’s navigation preload enabled flag .
-
Resolve promise with undefined.
3.6.2.
disable()
The
disable()
method,
when
invoked,
must
return
a
new
promise
promise
and
run
the
following
steps
in
parallel
:
-
Let registration be the context object 's associated service worker registration .
-
If registration ’s active worker is null, reject promise with an "
InvalidStateError
" exception, and abort these steps. -
Unset registration ’s navigation preload enabled flag .
-
Resolve promise with undefined.
3.6.3.
setHeaderValue(value)
The
setHeaderValue(
value
)
method,
when
invoked,
must
return
a
new
promise
promise
and
run
the
following
steps
in
parallel
:
-
Let registration be the context object 's associated service worker registration .
-
If registration ’s active worker is null, reject promise with an "
InvalidStateError
" exception, and abort these steps. -
Set registration ’s navigation preload header value to value .
-
Resolve promise with undefined.
3.6.4.
getState()
The
getState()
method,
when
invoked,
must
return
a
new
promise
promise
and
run
the
following
steps
in
parallel
:
-
Let registration be the context object 's associated service worker registration .
-
Let state be a new
NavigationPreloadState
dictionary. -
If registration ’s navigation preload enabled flag is set, set state ’s
enabled
dictionary member to true. -
Set state ’s
headerValue
dictionary member to the registration ’s navigation preload header value . -
Resolve promise with state .
4. Execution Context
// 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 { // A container for a list of Client objects that correspond to // browsing contexts (or shared workers) that are on the origin of this SW [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 onforeignfetch ; // eventattribute EventHandler onmessage ; // event.source of the message events is Client object };
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
importscripts
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
clients
attribute
must
return
the
Clients
object
that
is
associated
with
the
context
object
.
4.1.2.
registration
The
registration
attribute
must
return
the
ServiceWorkerRegistration
object
that
represents
the
service
worker
's
containing
service
worker
registration
.
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:
-
Let promise be a new promise .
-
Run the following substeps in parallel :
-
Set service worker 's skip waiting flag .
-
Resolve promise with undefined.
-
-
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
|
onforeignfetch
|
foreignfetch
|
onmessage
|
message
|
4.2.
Client
[Exposed =ServiceWorker ]interface {
Client readonly attribute USVString url ;readonly attribute DOMString id ;readonly attribute ClientType type ;readonly attribute boolean reserved ;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
A
Client
object
has
an
associated
service
worker
client
(a
service
worker
client
).
A
Client
object
has
an
associated
reserved
state
,
which
is
either
true
or
false.
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.
id
The
id
attribute
must
return
its
associated
service
worker
client
's
id
.
4.2.3.
type
The
type
attribute
must
run
these
steps:
-
If the context object 's
service workerclient is a type of environment or is a window client , return"window"
. -
Else if the context object 's
service workerclient is a dedicated worker client , return"worker"
. -
Else if the context object 's
service workerclient is a shared worker client , return"sharedworker"
. -
Else if the context object 's client is a service worker client , return
"serviceworker"
.
4.2.4.
reserved
The
reserved
attribute
must
return
the
context
object
’s
associated
reserved
state
.
4.2.5.
postMessage(message,
transfer)
The
postMessage(
message
,
transfer
)
method
must
run
these
steps:
-
Let sourceSettings be the context object ’s relevant settings object .
-
Let destination be the
ServiceWorkerContainer
object whoseservice workerclient is the context object ’sservice workerclient . -
If destination is null, throw an "
InvalidStateError
" exception. -
Let targetRealm be destination ’s relevant Realm .
-
Let cloneRecord be StructuredCloneWithTransfer ( message , transfer , targetRealm ). If this throws an exception, rethrow that exception and abort these steps.
-
Let clonedMessage be cloneRecord .[[Clone]].
-
Let newPorts be a new frozen array consisting of all
MessagePort
objects in cloneRecord .[[TransferList]], if any, maintaining their relative order. -
Add a task that runs the following steps to destination ’s client message queue :
-
Create an event e that uses the
MessageEvent
interface, with the event typemessage
, which does not bubble and is not cancelable. -
Let the data attribute of e be initialized to clonedMessage .
-
Let the origin attribute of e be initialized to the Unicode serialization of sourceSettings ’s origin .
-
Let the source attribute of e be initialized to a
ServiceWorker
object, which represents the service worker associated with sourceSettings ’s global object . -
Let the ports attribute of e be initialized to newPorts .
-
Dispatch e at destination .
-
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
service
worker
client
's
ancestor
origins
array
.
4.2.9.
focus()
The
focus()
method
must
run
these
steps:
-
If this algorithm is not triggered by user activation , return a promise rejected with an "
InvalidAccessError
" exception. -
Let promise be a new promise .
-
Run these substeps in parallel :
-
Let browsingContext be the context object ’s associated
service workerclient 's global object 's browsing context . -
Let visibilityState be null.
-
Let focusState be false.
-
Let ancestorOrigins be the empty array.
-
Queue a task task to run the following substeps on the context object ’s associated
service workerclient 's responsible event loop using the user interaction task source :-
Run the focusing steps with browsingContext .
-
Set visibilityState to browsingContext ’s active document ’s
visibilityState
attribute value. -
Set focusState to the result of running the has focus steps with browsingContext ’s active document as the argument.
-
Set ancestorOrigins to browsingContext ’s active document ’s relevant global object ’s
Location
object’s ancestor origins array .
-
-
Wait for task to have executed.
-
Let windowClient be the result of running Create Window Client algorithm with the context object ’s associated
service workerclient , visibilityState , focusState , and ancestorOrigins as the arguments. -
If windowClient ’s focus state is true, resolve promise with windowClient .
-
Else, reject promise with a
TypeError
.
-
-
Return promise .
4.2.10.
navigate(url)
The
navigate()
method
must
run
these
steps:
-
Let url be the result of parsing url with the context object ’s relevant settings object ’s API base URL .
-
If url is failure, return a promise rejected with a
TypeError
. -
If url is
about:blank
, return a promise rejected with aTypeError
. -
If the context object ’s associated
service workerclient 's active service worker is not the context object ’s relevant global object ’s service worker , return a promise rejected with aTypeError
. -
Let promise be a new promise .
-
Run these substeps in parallel :
-
Let browsingContext be the context object ’s associated
service workerclient 's global object 's browsing context . -
If browsingContext has discarded its
Document
, reject promise with aTypeError
and abort these steps. -
Let navigateFailed to false.
-
Let visibilityState be null.
-
Let focusState be false.
-
Let ancestorOrigins be the empty array.
-
Queue a task task to run the following substeps on the context object ’s associated
service workerclient 's responsible event loop using the user interaction task source :-
HandleNavigate : Navigate browsingContext to url with exceptions enabled . The source browsing context must be browsingContext .
-
If the algorithm steps invoked in the step labeled HandleNavigate throws an exception, set navigateFailed to true.
-
Set visibilityState to browsingContext ’s active document ’s
visibilityState
attribute value. -
Set focusState to the result of running the has focus steps with browsingContext ’s active document as the argument.
-
Set ancestorOrigins to browsingContext ’s active document ’s relevant global object ’s
Location
object’s ancestor origins array .
-
-
Wait for task to have executed (including its asynchronous steps).
-
If navigateFailed is true, reject promise with a
TypeError
and abort these steps. -
If browsingContext ’s
Window
object’s environment settings object ’s creation URL ’s origin is not the same as the service worker 's origin , then:-
Resolve promise with null.
-
Abort these steps.
-
-
Let windowClient be the result of running Create Window Client algorithm with browsingContext ’s
Window
object’s environment settings object , visibilityState , focusState , and ancestorOrigins as the arguments. -
Resolve promise with windowClient .
-
-
Return promise .
4.3.
Clients
[Exposed =ServiceWorker ]interface { // The objects returned will be new instances every time [
Clients NewObject ]Promise <any >get (DOMString ); [
id NewObject ]Promise <sequence <Client >>matchAll (optional ClientQueryOptions ); [
options NewObject ]Promise <WindowClient ?>openWindow (USVString ); [
url NewObject ]Promise <void >claim (); };
dictionary {
ClientQueryOptions boolean =
includeUncontrolled false ;boolean =
includeReserved false ;ClientType = "window"; };
type
enum {
ClientType ,
"window" ,
"worker" ,
"sharedworker" ,
"serviceworker" };
"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:
-
Let promise be a new promise .
-
Run these substeps in parallel :
-
For each
service workerclient client whose origin is the same as the associated service worker 's origin :-
If client ’s id is not id , continue to the next iteration of the loop.
-
If client is a type of environment , then:
-
If client ’s creation URL is not a potentially trustworthy URL , reject promise with a "
SecurityError
" exception and abort these steps.
-
-
Else:
-
If client is not a secure context , reject promise with a "
SecurityError
" exception and abort these steps.
-
-
If client is a type of environment or is a window client , then:
-
Let browsingContext be null.
-
Let visibilityState be null.
-
Let focusState be false.
-
Let ancestorOrigins be the empty array.
-
If client is a type of environment , set browsingContext to client ’s target browsing context .
-
Else, set browsingContext to client ’s global object 's browsing context .
-
Queue a task task to run the following substeps on browsingContext ’s event loop using the user interaction task source :
-
Set visibilityState to browsingContext ’s active document ’s
visibilityState
attribute value. -
Set focusState to the result of running the has focus steps with browsingContext ’s active document as the argument.
-
If client is a window client , set ancestorOrigins to browsingContext ’s active document ’s relevant global object ’s
Location
object’s ancestor origins array .
-
-
Wait for task to have executed.
-
Let windowClient be the result of running Create Window Client algorithm with client , visibilityState , focusState , and ancestorOrigins as the arguments.
-
Resolve promise with windowClient and abort these steps.
-
-
Else:
-
Let clientObject be the result of running Create Client algorithm with client as the argument.
-
Resolve promise with clientObject and abort these steps.
-
-
-
Resolve promise with undefined.
-
-
Return promise .
4.3.2.
matchAll(options)
The
matchAll(
options
)
method
must
run
these
steps:
-
Let promise be a new promise .
-
Run these substeps in parallel :
-
Let targetClients be an empty array.
-
For each
service workerclient client whose origin is the same as the associated service worker 's origin :-
If client is a type of environment , then:
-
If client ’s creation URL is not a potentially trustworthy URL , continue to the next iteration of the loop.
-
-
Else:
-
If client is not a secure context , continue to the next iteration of the loop.
-
-
If options .
includeUncontrolled
is false, then:-
If client ’s active service worker is not the associated service worker , continue to the next iteration of the loop.
-
-
If options .
includeReserved
is false, then:-
If client ’s execution ready flag is unset, continue to the next iteration of the loop.
-
-
Add client to targetClients .
-
-
Let matchedClients be an empty array.
-
For each
service workerclient client in targetClients :-
If client ’s global object is the current global object , then continue to the next iteration of the loop.
If options .
type
is"window"
or"all"
, and client is a type of environment or is a window client , then:-
Let browsingContext be null.
-
Let isClientEnumerable be true.
-
Let visibilityState be the empty string.
-
Let focusState be false.
-
Let ancestorOrigins be the empty array.
-
If client is a type of environment , set browsingContext to client ’s target browsing context .
-
Else, set browsingContext to client ’s global object 's browsing context .
-
Queue a task task to run the following substeps on browsingContext ’s event loop using the user interaction task source :
-
If browsingContext has been discarded , set isClientEnumerable to false and abort these steps.
-
If client is a window client and client ’s responsible document is not browsingContext ’s active document , set isClientEnumerable to false and abort these steps.
-
Set visibilityState to browsingContext ’s active document ’s
visibilityState
attribute value. -
Set focusState to the result of running the has focus steps with browsingContext ’s active document as the argument.
-
It client is a window client , set ancestorOrigins to browsingContext ’s active document ’s relevant global object ’s
Location
object’s ancestor origins array .
-
-
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.
-
If isClientEnumerable is true, then:
-
Let windowClient be the result of running Create Window Client algorithm with client , visibilityState , focusState , and ancestorOrigins as the arguments.
-
Add windowClient to matchedClients .
-
-
-
Else if options .
type
is"worker"
or"all"
and client is a dedicated worker client ,orthen:Let clientObject be the result of running Create Client algorithm with client as the argument.
Add clientObject to matchedClients .
Else if options .
type
is"sharedworker"
or"all"
and client is a shared worker client , then:-
Let clientObject be the result of running Create Client algorithm with client as the argument.
Add clientObject to matchedClients .
-
Else if options .
type
is"serviceworker"
or"all"
and client is a service worker client , then:Let clientObject be the result of running Create Client algorithm with client as the argument.
-
Add clientObject to matchedClients .
-
-
Sort matchedClients such that:
-
WindowClient
objects are always placed beforeClient
objects whose associatedservice workerclients are worker clients . -
WindowClient
objects that have been focused are placed first sorted in the most recently focused order, andWindowClient
objects that have never been focused are placed next sorted in theirservice workerclients ' creation order. -
Client
objects whose associatedservice workerclients are worker clients are placed next sorted in theirservice workerclients ' creation order.
-
-
Resolve promise with matchedClients .
-
-
Return promise .
4.3.3.
openWindow(url)
The
openWindow(
url
)
method
must
run
these
steps:
-
Let url be the result of parsing url with the context object ’s relevant settings object ’s API base URL .
-
If url is failure, return a promise rejected with a
TypeError
. -
If url is
about:blank
, return a promise rejected with aTypeError
. -
If this algorithm is not triggered by user activation , return a promise rejected with an "
InvalidAccessError
" exception. -
Let promise be a new promise .
-
Run these substeps in parallel :
-
Let newContext be a new top-level browsing context .
-
Let openWindowFailed to false.
-
Let visibilityState be null.
-
Let focusState be false.
-
Let ancestorOrigins be the empty array.
-
Queue a task task to run the following substeps on newContext ’s
Window
object’s environment settings object ’s responsible event loop using the user interaction task source :-
HandleNavigate : Navigate newContext to url with exceptions enabled and replacement enabled .
-
If the algorithm steps invoked in the step labeled HandleNavigate throws an exception, set openWindowFailed to true.
-
Set visibilityState to newContext ’s active document ’s
visibilityState
attribute value. -
Set focusState to the result of running the has focus steps with newContext ’s active document as the argument.
-
Set ancestorOrigins to newContext ’s active document ’s relevant global object ’s
Location
object’s ancestor origins array .
-
-
Wait for task to have executed (including its asynchronous steps).
-
If openWindowFailed is true, reject promise with a
TypeError
and abort these steps. -
If newContext ’s
Window
object’s environment settings object ’s creation URL ’s origin is not the same as the service worker 's origin , then:-
Resolve promise with null.
-
Abort these steps.
-
-
Let client be the result of running Create Window Client algorithm with newContext ’s
Window
object’s environment settings object , visibilityState , focusState , and ancestorOrigins as the arguments. -
Resolve promise with client .
-
-
Return promise .
4.3.4.
claim()
The
claim()
method
must
run
these
steps:
-
If the service worker is not an active worker , return a promise rejected with an "
InvalidStateError
" exception. -
Let promise be a new promise .
-
Run the following substeps in parallel :
-
For each
service workerclient client whose origin is the same as the service worker 's origin :-
If client is a type of environment , then:
-
If client ’s creation URL is not a potentially trustworthy URL , continue to the next iteration of the loop.
-
-
Else:
-
If client is not a secure context , continue to the next iteration of the loop.
-
-
Let registration be the result of running Match Service Worker Registration algorithm passing client ’s creation URL as the argument.
-
If registration is not the service worker 's containing service worker registration , continue to the next iteration of the loop.
-
If client ’s active service worker is not the service worker , then:
-
Invoke Handle
Service WorkerClient Unload with client as the argument. -
Set client ’s active service worker to service worker .
-
Invoke Notify Controller Change algorithm with client as the argument.
-
-
-
Resolve promise with undefined.
-
-
Return promise .
4.4.
ExtendableEvent
[Constructor (DOMString type ,optional ExtendableEventInit eventInitDict ),Exposed =ServiceWorker ]interface :
ExtendableEvent Event {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.
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)
waitUntil()
method
extends
the
lifetime
of
the
event.
waitUntil(
f
)
method
must
run
these
steps:
-
If the pending promises count is zero and the dispatch flag is unset, then:
-
Throw an "
InvalidStateError
" exception. -
Abort these steps.
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. -
-
Add f to the extend lifetime promises .
-
Increase the pending promises count by one.
Note: The pending promises count is increased even if the given promise has already been settled. The corresponding count decrease is done in the microtask queued by the reaction to the promise.
-
Upon fulfillment or rejection of f , queue a microtask to decrease the pending promises count by one.
The user agent should not terminate the service worker associated with event ’s relevant settings object ’s global object when event ’s dispatch flag is set or event ’s pending promises count is not zero. However, the user agent may impose a time limit to this lifetime extension.
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.
Service
workers
define
the
following
behaviors
for
install
event
and
activate
event,
respectively:
-
Adding a promise f to the event’s extend lifetime promises delays treating the installing worker as installed (i.e. a waiting worker ) until all the promises in the extend lifetime promises resolve successfully. (See step 11.3.1 of Install algorithm.) If f rejects, the installation fails. This is primarily used to ensure that a service worker is not considered installed (i.e. a waiting worker ) until all of the core caches it depends on are populated.
-
Adding a promise to the event’s extend lifetime promises delays treating the active worker as activated until all the promises in the extend lifetime promises settle. (See step 12.3 of Activate algorithm.) This is primarily used to ensure that any functional events are not dispatched to the
ServiceWorkerGlobalScope
object that represents the service worker until it upgrades database schemas and deletes the outdated cache entries.
4.5.
InstallEvent
[Constructor (DOMString type ,optional ExtendableEventInit eventInitDict ),Exposed =ServiceWorker ]interface :
InstallEvent ExtendableEvent {void registerForeignFetch (ForeignFetchOptions ); };
options dictionary {
ForeignFetchOptions required sequence <USVString >;
scopes required sequence <USVString >; };
origins
4.5.1.
event.registerForeignFetch(options)
registerForeignFetch(options)
registers
this
service
worker
to
handle
foreign
fetches
from
certain
origins
for
certain
sub
scopes.
registerForeignFetch(
options
)
method
must
run
these
steps:
-
If the dispatch flag is unset, then:
-
Throw an "
InvalidStateError
" exception. -
Abort these steps.
-
-
If options .
origins
is empty throw aTypeError
and abort these steps. -
Let originURLs be an empty list of URLs .
-
If the value of options .
origins
is not a single string equal to a single U+002A ASTERISK character (*):-
For each origin in options .origins:
-
If the value of origin is not an absolute-URL string , throw a
TypeError
and abort these steps. -
Add the result of parsing origin to originURLs .
-
-
-
If options .
scopes
is empty throw aTypeError
and abort these steps. -
Let scopeString be the context object ’s relevant global object ’s service worker 's containing service worker registration ’s scope url , serialized .
-
Let subScopeURLs be an empty list of URLs .
-
For each subScope in options .
scopes
:-
Let subScopeURL be the result of parsing subScope with context object ’s relevant settings object ’s API base URL .
-
If subScopeURL is failure, throw a
TypeError
and abort these steps. -
Let subScopeString be the serialized subScopeURL .
-
If subScopeString does not start with scopeString , throw a
TypeError
and abort these steps. -
Add subScopeURL to subScopeURLs .
-
-
Set this service worker 's list of foreign fetch scopes to subScopeURLs .
-
Set this service worker 's list of foreign fetch origins to originURLs .
4.6.
FetchEvent
[Constructor (DOMString type ,FetchEventInit eventInitDict ),Exposed =ServiceWorker ]interface :
FetchEvent ExtendableEvent { [SameObject ]readonly attribute Request request ;readonly attribute Promise <any >preloadResponse ;readonly attribute DOMString clientId ;readonly attribute DOMString reservedClientId ;readonly attribute DOMString targetClientId ;void respondWith (Promise <Response >); };
r
dictionary :
FetchEventInit ExtendableEventInit {required Request ;
request required Promise <any >;
preloadResponse DOMString = "";
clientId DOMString = "";
reservedClientId DOMString = ""; };
targetClientId
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.6.1.
event.request
request
attribute
must
return
the
value
it
was
initialized
to.
4.6.2.
event.preloadResponse
preloadResponse
attribute
must
return
the
value
it
was
initialized
to.
4.6.3.
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.6.4.
event.reservedClientId
reservedClientId
attribute
must
return
the
value
it
was
initialized
to.
When
an
event
is
created
the
attribute
must
be
initialized
to
the
empty
string.
4.6.5.
event.targetClientId
targetClientId
attribute
must
return
the
value
it
was
initialized
to.
When
an
event
is
created
the
attribute
must
be
initialized
to
the
empty
string.
4.6.6.
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:
-
If the dispatch flag is unset, then:
-
Throw an "
InvalidStateError
" exception. -
Abort these steps.
-
-
If the respond-with entered flag is set, then:
-
Throw an "
InvalidStateError
" exception. -
Abort these steps.
-
-
Add r to the extend lifetime promises .
-
Increase the pending promises count by one.
Note: The pending promises count is increased even if the given promise has already been settled. The corresponding count decrease is done in the microtask queued by the reaction to the promise.
-
Upon fulfillment or rejection of r , queue a microtask to decrease the pending promises count by one.
Note:
event.respondWith(r)
extends the lifetime of the event by default as ifevent.waitUntil(r)
is called. -
Set the stop propagation flag and stop immediate propagation flag .
-
Set the respond-with entered flag .
-
Set the wait to respond flag .
-
Let targetRealm be the relevant Realm of the context object .
-
Run the following substeps in parallel :
-
Wait until r settles.
-
If r rejected, then:
-
Set the respond-with error flag .
-
-
If r resolved with response , then:
-
If response is a
Response
object, then:-
If response is disturbed or locked , then:
-
Set the respond-with error flag .
-
-
Else:
-
Let bytes be an empty byte sequence.
-
Let end-of-body be false.
-
Let done be false.
-
Let potentialResponse be a copy of response ’s associated response , except for its body .
-
If response ’s body is non-null, run these substeps:
-
Let reader be the result of getting a reader from response ’s body 's stream .
-
Let strategy be an object created in targetRealm . The user agent may choose any object.
-
Let pull be an action that runs these subsubsteps:
-
Let promise be the result of reading a chunk from response ’s body 's stream with reader .
-
When promise is fulfilled with an object whose
done
property is false and whosevalue
property is aUint8Array
object, append the bytes represented by thevalue
property to bytes and perform ! DetachArrayBuffer with theArrayBuffer
object wrapped by thevalue
property. -
When promise is fulfilled with an object whose
done
property is true, set end-of-body to true. -
When promise is fulfilled with a value that matches with neither of the above patterns, or promise is rejected, error newStream with a
TypeError
.
-
-
Let cancel be an action that cancels response ’s body 's stream with reader .
-
Let newStream be the result of construct a ReadableStream object with strategy , pull and cancel in targetRealm .
-
Set potentialResponse ’s body to a new body whose stream is newStream .
-
Run these subsubsteps repeatedly in parallel while done is false:
-
If newStream is errored , then set done to true.
-
Otherwise, if bytes is empty and end-of-body is true, then close newStream and set done to true.
-
Otherwise, if bytes is not empty, run these subsubsubsteps:
-
Let chunk be a subsequence of bytes starting from the beginning of bytes .
-
Remove chunk from bytes .
-
Let buffer be an
ArrayBuffer
object created in targetRealm and containing chunk . -
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 .
-
-
Set the potential response to potentialResponse .
-
-
-
Else:
-
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.)
-
-
-
Unset the wait to respond flag .
-
4.7.
ForeignFetchEvent
[Constructor (DOMString type ,ForeignFetchEventInit eventInitDict ),Exposed =ServiceWorker ]interface :
ForeignFetchEvent ExtendableEvent { [SameObject ]readonly attribute Request request ;readonly attribute USVString origin ;void respondWith (Promise <ForeignFetchResponse >); };
r dictionary :
ForeignFetchEventInit ExtendableEventInit {required Request ;
request USVString = "null"; };
origin dictionary {
ForeignFetchResponse required Response ;
response USVString ;
origin sequence <ByteString >; };
headers
Service
workers
have
a
functional
event
foreignfetch
.
For
foreignfetch
events,
service
workers
use
the
ForeignFetchEvent
interface
which
extends
the
ExtendableEvent
interface.
Each
event
using
ForeignFetchEvent
interface
has
an
associated
potential
response
(a
response
),
initially
set
to
null,
an
associated
origin
(a
USVString
or
null),
initially
set
to
null,
an
associated
list
of
exposed
headers
(whose
element
type
is
a
byte
string),
initially
set
to
an
empty
list,
and
the
following
associated
flags
that
are
initially
unset:
-
wait to respond flag
-
respond-with entered flag
-
respond-with error flag
4.7.1.
event.request
The
request
attribute
must
return
the
value
it
was
initialized
to.
4.7.2.
event.origin
The
origin
attribute
must
return
the
value
it
was
initialized
to.
4.7.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:
-
If the dispatch flag is unset, then:
-
Throw an "
InvalidStateError
" exception. -
Abort these steps.
-
-
If the respond-with entered flag is set, then:
-
Throw an "
InvalidStateError
" exception. -
Abort these steps.
-
-
Add r to the extend lifetime promises .
-
Increase the pending promises count by one.
Note: The pending promises count is increased even if the given promise has already been settled. The corresponding count decrease is done in the microtask queued by the reaction to the promise.
-
Upon fulfillment or rejection of r , queue a microtask to decrease the pending promises count by one.
Note:
event.respondWith(r)
extends the lifetime of the event by default as ifevent.waitUntil(r)
is called. -
Set the stop propagation flag and stop immediate propagation flag .
-
Set the respond-with entered flag .
-
Set the wait to respond flag .
-
Let targetRealm be the relevant Realm of the context object .
-
Run the following substeps in parallel :
-
Wait until r settles.
-
If r rejected, then:
-
Set the respond-with error flag .
-
-
If r resolved with response , then:
-
If response is a
ForeignFetchResponse
, then:-
Set the list of exposed headers to response .
headers
. -
If response .
response
is disturbed or locked , then:-
Set the respond-with error flag .
-
-
Else:
-
Let bytes be an empty byte sequence.
-
Let end-of-body be false.
-
Let done be false.
-
Let potentialResponse be a copy of response .
response
's associated response , except for its body . -
If response .
response
's body is non-null, run these substeps:-
Let reader be the result of getting a reader from response .
response
's body 's stream . -
Let strategy be an object created in targetRealm . The user agent may choose any object.
-
Let pull be an action that runs these subsubsteps:
-
Let promise be the result of reading a chunk from response .
response
's body 's stream with reader . -
When promise is fulfilled with an object whose
done
property is false and whosevalue
property is aUint8Array
object, append the bytes represented by thevalue
property to bytes and perform ! DetachArrayBuffer with theArrayBuffer
object wrapped by thevalue
property. -
When promise is fulfilled with an object whose
done
property is true, set end-of-body to true. -
When promise is fulfilled with a value that matches with neither of the above patterns, or promise is rejected, error newStream with a
TypeError
.
-
-
Let cancel be an action that cancels response .
response
's body 's stream with reader . -
Let newStream be the result of construct a ReadableStream object with strategy , pull and cancel in targetRealm .
-
Set potentialResponse ’s body to a new body whose stream is newStream .
-
Run these subsubsteps repeatedly in parallel while done is false:
-
If newStream is errored , then set done to true.
-
Otherwise, if bytes is empty and end-of-body is true, then close newStream and set done to true.
-
Otherwise, if bytes is not empty, run these subsubsubsteps:
-
Let chunk be a subsequence of bytes starting from the beginning of bytes .
-
Remove chunk from bytes .
-
Let buffer be an
ArrayBuffer
object created in targetRealm and containing chunk . -
Enqueue a
Uint8Array
object created in targetRealm and wrapping buffer to newStream .
-
-
-
-
Set the potential response to potentialResponse .
-
-
Else:
-
Set the respond-with error flag .
Note: If the respond-with error flag is set, a network error is returned to Fetch through Handle Foreign Fetch algorithm. (See the step 19.1.) Otherwise, a filtered version of response is returned to Fetch through Handle Foreign Fetch algorithm. (See the step 20.1.)
-
-
-
Unset the wait to respond flag .
-
4.8.
ExtendableMessageEvent
[Constructor (DOMString type ,optional ExtendableMessageEventInit eventInitDict ),Exposed =ServiceWorker ]interface :
ExtendableMessageEvent ExtendableEvent {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.8.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.8.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.8.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.8.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.8.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.9. Events
The
following
events
are
dispatched
on
ServiceWorkerGlobalScope
object:
Event name | Interface | Dispatched when… |
---|---|---|
install
|
InstallEvent
| [ Lifecycle event ] The service worker 's containing service worker registration ’s installing worker changes. (See step 11.2 of the Install algorithm.) |
activate
|
ExtendableEvent
| [ Lifecycle event ] The service worker 's containing service worker registration ’s active worker changes. (See step 12.2 of the Activate algorithm.) |
fetch
|
FetchEvent
|
[
Functional
event
]
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.)
|
foreignfetch
|
FetchEvent
|
[
Functional
event
]
The
http
fetch
invokes
Handle
Foreign
Fetch
with
request
.
As
a
result
of
performing
Handle
Foreign
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.)
|
message
|
ExtendableMessageEvent
| When it receives a message. |
5.
Link
type
"
serviceworker
"
The
serviceworker
keyword
may
be
used
with
link
elements.
This
keyword
creates
an
external
resource
link
(
serviceworker
link
)
that
is
used
to
declare
a
service
worker
registration
and
its
scope
url
.
5.1.
Processing
the
Link
header
When
a
user
agent
that
supports
[RFC5988]
processes
a
Link
header
that
contains
a
serviceworker
link
,
the
user
agent
should
run
these
steps:
-
If the
Link
header has an "anchor
" parameter, abort these steps. -
Let contextURL be the result of parsing the context IRI of the
Link
header. -
If the result of running potentially trustworthy origin with the origin of contextURL is
Not Trusted
, abort these steps. -
Let request be the request for which this header was received in the response.
-
If request ’s client is not a secure context , abort these steps.
-
Let scriptURL be the result of parsing the target IRI of the
Link
header. -
Let scopeURL be null.
-
If the "
scope
" target attribute of theLink
header is present, set scopeURL to the result of parsing the "scope
" target attribute with scriptURL . -
Let workerType be the "
workertype
" target attribute of theLink
header, or "classic
" if no such attribute is present. -
If workerType is not a valid
WorkerType
value, abort these steps. -
Let useCache be true if the
Link
header has a target attribute named "usecache
", otherwise false. -
Invoke Start Register with scopeURL , scriptURL , a new promise , null, contextURL , workerType , and useCache .
5.2.
Processing
the
link
element
When
a
serviceworker
link
’s
link
element
is
inserted
into
a
document
,
or
a
serviceworker
link
is
created
on
a
link
element
that
is
already
in
a
document
tree
,
or
the
href
or
scope
attributes
of
the
link
element
of
a
serviceworker
link
is
changed,
the
user
agent
should
run
these
steps:
-
If the
href
attribute is the empty string, abort these steps. -
Let client be the document’s
service workerclient . -
If client is not a secure context , queue a task to fire an event named
error
at thelink
element, and abort these steps. -
Let scriptURL be the result of parsing the
href
attribute with thelink
element’s node document ’s document base URL . -
Let scopeURL be null.
-
If the
scope
attribute is present, set scopeURL to the result of parsing thescope
attribute with thelink
element’s node document ’s document base URL . -
Let workerType be the
workertype
attribute, or "classic
" if theworkertype
attribute is omitted. -
If workerType is not a valid
WorkerType
value, queue a task to fire an event namederror
at thelink
element, and abort these steps. -
Let useCache be true if the
link
element has ausecache
attribute, otherwise false. -
Let promise be a new promise .
-
Invoke Start Register with scopeURL , scriptURL , promise , client , client ’s creation URL , workerType , and useCache .
-
Run the following substeps in parallel :
-
Wait until promise settles.
-
If promise rejected, queue a task to fire an event named
error
at thelink
element. -
If promise resolved, queue a task to fire an event named
load
at thelink
element.
-
The serviceworker link element must not delay the load event of the element’s node document .
Link: </js/sw.js>; rel="serviceworker"; scope="/"
has
more
or
less
the
same
effect
as
a
document
being
loaded
in
a
secure
context
with
the
following
link
element:
< link rel = "serviceworker" href = "/js/sw.js" scope = "/" >
which is more or less equivalent to the page containing javascript code like:
navigator. serviceworker. register( "/js/sw.js" , { scope: "/" });
5.3. Link element interface extensions
partial interface HTMLLinkElement { [CEReactions ]attribute USVString scope ; [CEReactions ]attribute WorkerType workerType ; [CEReactions ]attribute boolean useCache ; };
The
scope
IDL
attribute
must
reflect
the
element’s
scope
content
attribute.
The
workerType
IDL
attribute
must
reflect
the
element’s
workertype
content
attribute.
The
useCache
IDL
attribute
must
reflect
the
element’s
usecache
content
attribute.
6. 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.
6.1. Constructs
A
fetching
record
is
a
Record
{[[key]],
[[value]]}
where
[[key]]
is
a
Request
and
[[value]]
is
a
Response
.
A fetching record has an associated incumbent record (a fetching record ). It is initially set to null.
A request to response map is a List of fetching records .
A
name
to
cache
map
is
an
ordered
map
where
the
keys
are
strings
that
represents
a
name
of
the
Cache
object,
and
the
values
are
Cache
objects.
Each origin has an associated name to cache map .
6.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.
6.3.
self.caches
partial interface WindowOrWorkerGlobalScope { [SecureContext ,SameObject ]readonly attribute CacheStorage caches ; };
6.3.1.
caches
caches
attribute
must
return
this
object’s
associated
CacheStorage
object.
6.4.
Cache
[SecureContext ,Exposed =(Window ,Worker )]interface { [
Cache NewObject ]Promise <any >match (RequestInfo ,
request optional CacheQueryOptions ); [
options NewObject ]Promise <sequence <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 <sequence <Request >>keys (optional RequestInfo ,
request optional CacheQueryOptions ); };
options
dictionary {
CacheQueryOptions boolean =
ignoreSearch false ;boolean =
ignoreMethod false ;boolean =
ignoreVary false ;DOMString ; };
cacheName
dictionary {
CacheBatchOperation DOMString ;
type Request ;
request Response ;
response CacheQueryOptions ; };
options
A
Cache
object
represents
a
request
to
response
map
.
Multiple
separate
objects
implementing
the
Cache
interface
across
documents
and
workers
can
all
be
associated
with
the
same
request
to
response
map
simultaneously.
Cache
objects
are
always
enumerable
via
self.caches
in
insertion
order
(per
ECMAScript
6
Map
objects
).
6.4.1.
match(request,
options)
match(
request
,
options
)
method
must
run
these
steps:
-
Let promise be a new promise .
-
Run these substeps in parallel :
-
Let p be the result of running the algorithm specified in
matchAll(request, options)
method with request and options as the arguments. -
Wait until p settles.
-
If p rejects with an exception, then:
-
Reject promise with that exception.
-
-
Else if p resolves with an array, responseArray , then:
-
If responseArray is an empty array, then:
-
Resolve promise with undefined.
-
-
Else:
-
Resolve promise with the first element of responseArray .
-
-
-
-
Return promise .
6.4.2.
matchAll(request,
options)
matchAll(
request
,
options
)
method
must
run
these
steps:
-
Let r be null.
-
If the optional argument request is not omitted, then:
-
If request is a
Request
object, then: -
Else if request is a string, then:
-
-
Let promise be a new promise .
-
Run these substeps in parallel :
-
Let responseArray be an empty array.
-
If the optional argument request is omitted, then:
-
For each fetching record entry of its request to response map , in key insertion order:
-
Add a copy of entry .[[value]] to responseArray .
-
-
Resolve promise with responseArray .
-
Abort these steps.
-
-
Else:
-
Let entries be the result of running Query Cache algorithm passing a
Request
object associated with r and options as the arguments. -
For each entry of entries :
-
Let response be null.
-
If the incumbent record incumbentRecord of the corresponding fetching record in request to response map is not null, set response to a copy of incumbentRecord .[[value]].
-
Else, set response to a copy of entry [1].
-
Add response to responseArray .
-
-
Resolve promise with responseArray .
-
-
-
Return promise .
6.4.3.
add(request)
add(
request
)
method
must
run
these
steps:
-
Let requests be an array containing only request .
-
Set responseArrayPromise to the result of running the algorithm specified in
addAll(requests)
passing requests as the argument. -
Return the result of transforming responseArrayPromise with a fulfillment handler that returns undefined.
6.4.4.
addAll(requests)
addAll(
requests
)
method
must
run
these
steps:
-
Let responsePromiseArray be an empty array.
-
Let requestArray be an empty array.
-
For each request whose type is
Request
in requests : -
For each request in requests :
-
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. -
If r ’s url 's scheme is not one of "
http
" and "https
", then: -
Set r ’s initiator to "
fetch
" and destination to "subresource
". -
Add a
Request
object associated with r to requestArray . -
Let responsePromise be a new promise .
-
Run the following substeps in parallel :
-
Fetch r .
-
To process response for response , run these substeps:
-
If response ’s type is "
error
", or response ’s status is not an ok status , reject responsePromise with aTypeError
. -
Else if response ’s header list contains a header named `
Vary
`, then:-
Let varyHeaders be the array containing the elements corresponding to the field-values of the Vary header.
-
Let matchAsterisk be false.
-
For each f in varyHeaders :
-
If f matches "
*
", set matchAsterisk to true and break the loop.
-
-
If matchAsterisk is true, reject responsePromise with a
TypeError
. -
Else, resolve responsePromise with a new
Response
object associated with response and a newHeaders
object whose guard is "immutable
".
-
-
Else, resolve responsePromise with a new
Response
object associated with response and a newHeaders
object whose guard is "immutable
".
Note: This step ensures that the promise for this fetch resolves as soon as the response’s headers become available.
-
-
To process response end-of-body for response , do nothing.
-
To process response done for response , do nothing.
-
-
Add responsePromise to responsePromiseArray .
-
-
Let p be waiting for all of responsePromiseArray .
-
Return the result of transforming p with a fulfillment handler that, when called with argument responseArray , performs the following substeps in parallel :
-
Let operations be an empty array.
-
For each response in responseArray with the index index :
-
Let o be an empty object representing a
CacheBatchOperation
dictionary. -
Set the
type
dictionary member of o to "put". -
Set the
request
dictionary member of o to requestArray [ index ]. -
Set the
response
dictionary member of o to response . -
Add o to operations .
-
-
Let resultPromise be the result of running Batch Cache Operations algorithm passing operations as the argument.
-
Return the result of transforming resultPromise with a fulfillment handler that, when called with argument responses , performs the following substeps in parallel :
-
Let responseBodyPromiseArray be an empty array.
-
For each response in responses :
-
Let responseBodyPromise be a new promise .
-
Run the following substeps in parallel :
-
Wait for either end-of-file to have been pushed to response ’s associated response r ’s body or for r to have a termination reason .
-
If r had a termination reason , then:
-
If the incumbent record incumbentRecord of the corresponding fetching record fetchingRecord in request to response map is not null, then:
-
Set fetchingRecord in request to response map to the copy of incumbentRecord .
-
-
Else:
-
Delete fetchingRecord from request to response map .
-
-
Reject responseBodyPromise with a
TypeError
.
-
-
Else:
-
Set the incumbent record of the corresponding fetching record fetchingRecord in request to response map to the copy of fetchingRecord .
-
Let invalidRecords be the result of running Query Cache algorithm passing fetchingRecord .[[key]] as the argument.
-
For each invalidRecord in invalidRecords :
-
If invalidRecord is not fetchingRecord , delete it from request to response map .
-
-
Resolve responseBodyPromise with response .
-
-
-
Add responseBodyPromise to responseBodyPromiseArray .
-
-
Let q be waiting for all of responseBodyPromiseArray .
-
Return the result of transforming q with a fulfillment handler that returns undefined.
-
-
6.4.5.
put(request,
response)
put(
request
,
response
)
method
must
run
these
steps:
-
Let r be null.
-
If request is a
Request
object, then: -
Else if request is a string, then:
-
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. -
If r ’s url 's scheme is not one of "
http
" and "https
", return a promise rejected with aTypeError
.
-
-
If response ’s associated response 's header list contains a header named `
Vary
`, then:-
Let varyHeaders be the array containing the elements corresponding to the field-values of the Vary header.
-
For each f in varyHeaders :
-
If f matches "
*
", return a promise rejected with aTypeError
.
-
-
-
If response is disturbed or locked , return a promise rejected with a
TypeError
. -
Let newResponse be a new
Response
object associated with response ’s associated response and a newHeaders
object whose guard is response ’sHeaders
' guard . -
If response ’s body is non-null, run these substeps:
-
Let dummyStream be an empty
ReadableStream
object. -
Set response ’s body to a new body whose stream is dummyStream .
-
Let reader be the result of getting a reader from dummyStream .
-
Read all bytes from dummyStream with reader .
-
-
Let operations be an empty array.
-
Let o be an empty object representing a
CacheBatchOperation
dictionary. -
Set the
type
dictionary member of o to "put". -
Set the
request
dictionary member of o to aRequest
object associated with r . -
Set the
response
dictionary member of o to newResponse . -
Add o to operations .
-
Let resultPromise be the result of running Batch Cache Operations passing operations as the argument.
-
Return the result of transforming resultPromise with a fulfillment handler that, when called with argument responses , performs the following substeps in parallel :
-
Wait for either end-of-file to have been pushed to responses [0]'s associated response r ’s body or for r to have a termination reason .
-
If r had a termination reason , then:
-
If the incumbent record incumbentRecord of the corresponding fetching record fetchingRecord in request to response map is not null, then:
-
Set fetchingRecord in request to response map to the copy of incumbentRecord .
-
-
Else:
-
Delete fetchingRecord from request to response map .
-
-
Throw a
TypeError
.
-
-
Else:
-
Set the incumbent record of the corresponding fetching record fetchingRecord in request to response map to the copy of fetchingRecord .
-
Let invalidRecords be the result of running Query Cache algorithm passing fetchingRecord .[[key]] as the argument.
-
For each invalidRecord in invalidRecords :
-
If invalidRecord is not fetchingRecord , delete it from request to response map .
-
-
Return undefined.
-
-
6.4.6.
delete(request,
options)
delete(
request
,
options
)
method
must
run
these
steps:
-
Let r be null.
-
If request is a
Request
object, then: -
Else if request is a string, then:
-
Let operations be an empty array.
-
Let o be an empty object representing a
CacheBatchOperation
dictionary. -
Set the
type
dictionary member of o to "delete". -
Set the
request
dictionary member of o to aRequest
object associated with r . -
Set the
options
dictionary member of o to options . -
Add o to operations .
-
Let resultPromise be the result of running Batch Cache Operations passing operations as the argument.
-
Return the result of transforming resultPromise with a fulfillment handler, when called with argument responseArray , performs the following substeps in parallel :
-
If responseArray is not null, return true.
-
Else, return false.
-
6.4.7.
keys(request,
options)
keys(
request
,
options
)
method
must
run
these
steps:
-
Let promise be a new promise .
-
Run these substeps in parallel :
-
Let resultArray be an empty array.
-
If the optional argument request is omitted, then:
-
For each fetching record entry of its request to response map , in key insertion order:
-
Add entry .[[key]] to resultArray .
-
-
-
Else:
-
Let r be null.
-
If request is a
Request
object, then: -
Else if request is a string, then:
-
Let requestResponseArray be the result of running Query Cache algorithm passing a
Request
object that represents r and options as the arguments. -
For each requestResponse in requestResponseArray :
-
Add requestResponse [0] to resultArray .
-
-
-
Resolve promise with resultArray .
-
-
Return promise .
6.5.
CacheStorage
[SecureContext ,Exposed =(Window ,Worker )]interface { [
CacheStorage NewObject ]Promise <any >match (RequestInfo ,
request optional CacheQueryOptions ); [
options NewObject ]Promise <boolean >has (DOMString ); [
cacheName NewObject ]Promise <Cache >open (DOMString ); [
cacheName NewObject ]Promise <boolean >delete (DOMString ); [
cacheName NewObject ]Promise <sequence <DOMString >>keys (); };
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.
6.5.1.
match(request,
options)
match(
request
,
options
)
method
must
run
these
steps:
-
If options .
cacheName
is present , then:-
Return a new promise p and run the following substeps in parallel :
-
For each cacheName → cache of name to cache map :
-
If options .
cacheName
matches cacheName , then:-
Resolve p with the result of running the algorithm specified in
match(request, options)
method ofCache
interface with request and options as the arguments (providing cache as thisArgument to the [[Call]] internal method ofmatch(request, options)
.) -
Abort these steps.
-
-
-
Resolve p with undefined.
-
-
-
Else:
-
Let p be a promise resolved with undefined.
-
For each cacheName → cache of name to cache map :
-
Set p to the result of transforming itself with a fulfillment handler that, when called with argument v , performs the following substeps in parallel :
-
If v is not undefined, return v .
-
Return the result of running the algorithm specified in
match(request, options)
method ofCache
interface with request and options as the arguments (providing cache ] as thisArgument to the [[Call]] internal method ofmatch(request, options)
.)
-
-
-
Return p .
-
6.5.2.
has(cacheName)
has(
cacheName
)
method
must
run
these
steps:
-
Return a promise resolved with the result of running the following substeps:
-
For each key → value of name to cache map :
-
If cacheName matches key , then:
-
Return true.
-
-
-
Return false.
-
6.5.3.
open(cacheName)
open(
cacheName
)
method
must
run
these
steps:
-
Let p be a new promise .
-
Run the following substeps:
-
For each key → value of name to cache map :
-
If cacheName matches key , then:
-
Resolve p with a new
Cache
object which is a copy of value . -
Abort these steps.
-
-
-
Let cache be a new
Cache
object. -
Set name to cache map [ cacheName ] to cache . If this cache write operation failed due to exceeding the granted quota limit, reject p with a "
QuotaExceededError
" exception and abort these steps. -
Resolve p with cache .
-
-
Return p .
6.5.4.
delete(cacheName)
delete(
cacheName
)
method
must
run
these
steps:
-
Let p be the result of running the algorithm specified in
has(cacheName)
method with cacheName as the argument. -
Return the result of transforming p with a fulfillment handler that, when called with argument cacheExists , performs the following substeps in parallel :
-
If cacheExists is true, then:
-
Delete a Record {[[key]], [[value]]} entry from its name to cache map where cacheName matches entry.[[key]].
-
Return true.
-
Abort these steps.
Note: After this step, the existing DOM objects (i.e. the currently referenced Cache, Request, and Response objects) should remain functional.
-
-
Else:
-
Return false.
-
-
6.5.5.
keys()
keys()
method
must
run
these
steps:
Note: The promise returned from this method resolves with the sequence of keys, cache names in DOMString, in insertion order.
-
Let cacheKeys be the result of getting the keys of name to cache map .
-
Return cacheKeys .
7. Security Considerations
7.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
.
This
effectively
means
that
service
workers
and
their
service
worker
clients
should
be
hosted
over
HTTPS.
A
user
agent
may
allow
localhost
,
127.0.0.0/8
,
and
::1/128
for
development
purpose.
(Note
that
they
may
still
be
secure
contexts
.)
The
primary
reason
for
this
restriction
is
to
protect
users
from
the
risks
associated
with
insecure
contexts
.
7.2. Content Security Policy
Whenever a user agent invokes 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).
7.3. Origin Relativity
7.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.
7.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
:
-
Let serviceWorker be request ’s client 's global object 's service worker .
-
If serviceWorker ’s imported scripts updated flag is unset, then:
-
Let registration be serviceWorker ’s containing service worker registration .
-
Set request ’s cache mode to "
no-cache
" if any of the following are true:-
registration ’s use cache is false.
-
The current global object 's force bypass cache for importscripts flag is set.
-
registration ’s last update check time is not null and the time difference in seconds calculated by the current time minus registration ’s last update check time is greater than 86400.
-
-
Let response be the result of fetching request .
-
If response ’s cache state is not "
local
", set registration ’s last update check time to the current time. -
Extract a MIME type from the response ’s unsafe response 's header list . If this MIME type (ignoring parameters) is not one of
text/javascript
,application/x-javascript
, andapplication/javascript
, return a network error . -
If response ’s unsafe response ’s type is not "
error
", and response ’s status is an ok status , then:-
Set script resource map [ request ’s url ] to response .
-
-
Return response .
-
-
Else:
-
If script resource map [ url ] exists , return script resource map [ url ].
-
Else, return a network error .
-
7.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
<script>
,
<img>
,
<video>
and
<link>
elements.
It
would
be
hugely
limiting
if
this
sort
of
runtime
collaboration
broke
when
offline.
Similarly,
it
is
possible
to
fetch
many
sorts
of
off-
origin
resources
when
appropriate
CORS
headers
are
set.
Service
workers
enable
this
by
allowing
Caches
to
fetch
and
cache
off-origin
items.
Some
restrictions
apply,
however.
First,
unlike
same-origin
resources
which
are
managed
in
the
Cache
as
Response
objects
whose
corresponding
responses
are
basic
filtered
response
,
the
objects
stored
are
Response
objects
whose
corresponding
responses
are
either
CORS
filtered
responses
or
opaque
filtered
responses
.
They
can
be
passed
to
event.respondWith(r)
method
in
the
same
manner
as
the
Response
objects
whose
corresponding
responses
are
basic
filtered
responses
,
but
cannot
be
meaningfully
created
programmatically.
These
limitations
are
necessary
to
preserve
the
security
invariants
of
the
platform.
Allowing
Caches
to
store
them
allows
applications
to
avoid
re-architecting
in
most
cases.
7.5. Implementer Concerns
This section is non-normative.
The implementers are encouraged to note:
-
Plug-ins should not load via service workers . As plug-ins may get their security origins from their own urls, the embedding service worker cannot handle it. For this reason, the Handle Fetch algorithm makes the potential-navigation-or-subresource request (whose context is either
<embed>
or<object>
) immediately fallback to the network without dispatchingfetch
event. -
Some of the legacy networking stack code may need to be carefully audited to understand the ramifications of interactions with service workers .
7.6. Privacy
Service workers introduce new persistent storage features including scope to registration map (for service worker registrations and their service workers ), request to response map and name to cache map (for caches), and script resource map (for script resources). In order to protect users from any potential unsanctioned tracking threat, these persistent storages should be cleared when users intend to clear them and should maintain and interoperate with existing user controls e.g. purging all existing persistent storages.
8. Extensibility
Service workers are extensible from other specifications.
8.1. Define API bound to Service Worker Registration
Specifications
may
define
an
API
tied
to
a
service
worker
registration
by
using
partial
interface
definition
to
the
ServiceWorkerRegistration
interface
where
it
may
define
the
specification
specific
attributes
and
methods:
partial interface ServiceWorkerRegistration { // e.g. define an API namespacereadonly attribute APISpaceType APISpace ; // e.g. define a methodPromise <T >methodName (/* list of arguments */); };
8.2. Define Functional Event
Specifications
may
define
a
functional
event
by
extending
ExtendableEvent
interface:
// e.g. define FunctionalEvent interfaceinterface FunctionalEvent :ExtendableEvent { // add a functional event’s own attributes and methods };
8.3. Define Event Handler
Specifications
may
define
an
event
handler
attribute
for
the
corresponding
functional
event
using
partial
interface
definition
to
the
ServiceWorkerGlobalScope
interface:
partial interface ServiceWorkerGlobalScope {attribute EventHandler onfunctionalevent ; };
8.4. Request Functional Event Dispatch
To request a functional event dispatch to a service worker , specifications may invoke Handle Functional Event algorithm with its service worker registration registration and the algorithm callbackSteps as the arguments.
Specifications
may
define
an
algorithm
callbackSteps
where
the
corresponding
functional
event
can
be
created
and
fired
with
specification
specific
objects.
The
algorithm
is
passed
globalObject
(a
ServiceWorkerGlobalScope
object)
at
which
it
may
fire
its
functional
events
.
This
algorithm
is
called
on
a
task
queued
by
Handle
Functional
Event
algorithm.
Note: See an example hook defined in Notifications API .
Appendix A: Algorithms
The following definitions are the user agent’s internal data structures used throughout the specification.
A scope to registration map is an ordered map where the keys are scope urls and the values are service worker registrations .
A job is an abstraction of one of register, update, and unregister request for a service worker registration .
A job has a scope url (a URL ).
A job has a script url (a URL ).
A
job
has
a
worker
type
("
classic
"
or
"
module
").
A job has a use cache (a boolean).
A
job
has
a
client
(a
service
worker
client
).
It
is
initially
null.
A job has a referrer (a URL or null).
A job has a job promise (a promise ). It is initially null.
A job has a list of equivalent jobs (a list of jobs ). It is initially the empty list.
A job has a force bypass cache flag . It is initially unset.
Two jobs are equivalent when their job type is the same and:
-
For register and update jobs , both their scope url and the script url are the same.
A job queue is a thread safe queue used to synchronize the set of concurrent jobs . The job queue contains jobs as its elements. The job queue should satisfy the general properties of FIFO queue. A user agent must maintain a separate job queue for each service worker registration keyed by its scope url . A job queue is initially empty. Unless stated otherwise, the job queue referenced from the algorithm steps is a job queue for the job ’s scope url .
Create Job
- Input
-
jobType , a job type
scopeURL , a URL
scriptURL , a URL
promise , a promise
client , a
service workerclient - Output
-
job , a job
-
Let job be a new job .
-
Set job ’s job type to jobType .
-
Set job ’s scope url to scopeURL .
-
Set job ’s script url to scriptURL .
-
Set job ’s job promise to promise .
-
Set job ’s client to client .
-
If client is not null, set job ’s referrer to client ’s creation URL .
-
Return job .
Schedule Job
- Input
-
job , a job
- Output
-
none
-
If the job queue is empty, then:
-
Else:
-
Let lastJob be the element at the back of the job queue .
-
If job is equivalent to lastJob and lastJob ’s job promise has not settled, append job to lastJob ’s list of equivalent jobs .
-
Else, push job to the job queue .
-
Run Job
- Input
-
none
- Output
-
none
-
Assert: the job queue is not empty.
-
Queue a task to run these steps:
-
Let job be the element in the front of the job queue .
-
If job ’s job type is register , run Register with job in parallel .
-
Else if job ’s job type is update , run Update with job in parallel .
Note: For a register job and an update job, the user agent delays queuing a task for running the job until after the document initiated the job has been dispatched
DOMContentLoaded
event. -
Else if job ’s job type is unregister , run Unregister with job in parallel .
-
Finish Job
- Input
-
job , a job
- Output
-
none
Resolve Job Promise
- Input
-
job , a job
value , any
- Output
-
none
-
If job ’s client is not null, queue a task to resolve job ’s job promise with value on job ’s client 's responsible event loop using the DOM manipulation task source as the task source .
-
For each equivalentJob in job ’s list of equivalent jobs :
-
If equivalentJob ’s client is not null, queue a task to resolve equivalentJob ’s job promise with value on equivalentJob ’s client 's responsible event loop using the DOM manipulation task source as the task source .
-
Reject Job Promise
-
If job ’s client is not null, queue a task to reject job ’s job promise with reason on job ’s client 's responsible event loop using the DOM manipulation task source as the task source .
-
For each equivalentJob in job ’s list of equivalent jobs :
-
If equivalentJob ’s client is not null, queue a task to reject equivalentJob ’s job promise with reason on equivalentJob ’s client 's responsible event loop using the DOM manipulation task source as the task source .
-
Start Register
- Input
-
scopeURL , a URL or failure or null
scriptURL , a URL or failure
promise , a promise
client , a
service workerclientreferrer , a URL
workerType , a worker type
useCache , a boolean
- Output
-
none
-
If scriptURL is failure, reject promise with a
TypeError
and abort these steps. -
If scriptURL ’s scheme is not one of "
http
" and "https
", reject promise with aTypeError
and abort these steps. -
If any of the strings in scriptURL ’s path contains either ASCII case-insensitive "
%2f
" or ASCII case-insensitive "%5c
", reject promise with aTypeError
and abort these steps. -
If scopeURL is null, set scopeURL to the result of parsing the string "
./
" with scriptURL .Note: The scope url for the registration is set to the location of the service worker script by default.
-
If scopeURL is failure, reject promise with a
TypeError
and abort these steps. -
If scopeURL ’s scheme is not one of "
http
" and "https
", reject promise with aTypeError
and abort these steps. -
If any of the strings in scopeURL ’s path contains either ASCII case-insensitive "
%2f
" or ASCII case-insensitive "%5c
", reject promise with aTypeError
and abort these steps. -
Let job be the result of running Create Job with register , scopeURL , scriptURL , promise , and client .
-
Set job ’s worker type to workerType .
-
Set job ’s use cache to useCache .
-
Set job ’s referrer to referrer .
-
Invoke Schedule Job with job .
Register
- Input
-
job , a job
- Output
-
none
-
If the result of running potentially trustworthy origin with the origin of job ’s script url as the argument is
Not Trusted
, then:-
Invoke Reject Job Promise with job and a "
SecurityError
" exception. -
Invoke Finish Job with job and abort these steps.
-
-
If the origin of job ’s script url is not job ’s referrer 's origin , then:
-
Invoke Reject Job Promise with job and a "
SecurityError
" exception. -
Invoke Finish Job with job and abort these steps.
-
-
If the origin of job ’s scope url is not job ’s referrer 's origin , then:
-
Invoke Reject Job Promise with job and a "
SecurityError
" exception. -
Invoke Finish Job with job and abort these steps.
-
-
Let registration be the result of running the Get Registration algorithm passing job ’s scope url as the argument.
-
If registration is not null, then:
-
If registration ’s uninstalling flag is set, unset it.
-
Let newestWorker be the result of running the Get Newest Worker algorithm passing registration as the argument.
-
If newestWorker is not null, job ’s script url equals newestWorker ’s script url with the exclude fragments flag set, and job ’s use cache 's value equals registration ’s use cache 's value, then:
-
Invoke Resolve Job Promise with job and the
ServiceWorkerRegistration
object which represents registration . -
Invoke Finish Job with job and abort these steps.
-
-
-
Else:
-
Invoke Set Registration algorithm with job ’s scope url and job ’s use cache .
-
-
Invoke Update algorithm passing job as the argument.
Update
- Input
-
job , a job
- Output
-
none
-
Let registration be the result of running the Get Registration algorithm passing job ’s scope url as the argument.
-
If registration is null or registration ’s uninstalling flag is set, then:
-
Invoke Reject Job Promise with job and a
TypeError
. -
Invoke Finish Job with job and abort these steps.
-
-
Let newestWorker be the result of running Get Newest Worker algorithm passing registration as the argument.
-
If job ’s job type is update , and newestWorker ’s script url does not equal job ’s script url with the exclude fragments flag set, then:
-
Invoke Reject Job Promise with job and a
TypeError
. -
Invoke Finish Job with job and abort these steps.
-
-
Let httpsState be "
none
". -
Let referrerPolicy be the empty string.
-
Switching on job ’s worker type , run these substeps with the following options:
-
"
classic
" -
Fetch a classic worker script given job ’s serialized script url , job ’s client , "
serviceworker
", and the to-be-created environment settings object for this service worker. -
"
module
" -
Fetch a module worker script graph given job ’s serialized script url , job ’s client , "
serviceworker
", "omit
", and the to-be-created environment settings object for this service worker.
To perform the fetch given request , run the following steps:
-
Set request ’s cache mode to "
no-cache
" if any of the following are true:-
registration ’s use cache is false.
-
job ’s force bypass cache flag is set.
-
newestWorker is not null, and registration ’s last update check time is not null and the time difference in seconds calculated by the current time minus registration ’s last update check time is greater than 86400.
Note: Even if the cache mode is not set to "
no-cache
", the user agent obeys Cache-Control header’s max-age value in the network layer to determine if it should bypass the browser cache. -
-
Set request ’s skip-service-worker flag .
-
If the is top-level flag is unset, then return the result of fetching request .
-
Append `
Service-Worker
`/`script
` to request ’s header list .Note: See the definition of the Service-Worker header in Appendix B: Extended HTTP headers.
-
Set request ’s redirect mode to "
error
". -
Fetch request , and asynchronously wait to run the remaining steps as part of fetch’s process response for the response response .
-
Extract a MIME type from the response ’s header list . If this MIME type (ignoring parameters) is not one of
text/javascript
,application/x-javascript
, andapplication/javascript
, then:-
Invoke Reject Job Promise with job and a "
SecurityError
" exception. -
Asynchronously complete these steps with a network error .
-
-
Let serviceWorkerAllowed be the result of parsing `
Service-Worker-Allowed
` in response ’s header list .Note: See the definition of the Service-Worker-Allowed header in Appendix B: Extended HTTP headers.
-
Set httpsState to response ’s HTTPS state .
-
Set referrerPolicy to the result of parse a referrer policy from a
Referrer-Policy
header of response . -
If serviceWorkerAllowed is failure, then:
-
Asynchronously complete these steps with a network error .
-
-
Let scopeURL be registration ’s scope url .
-
Let maxScopeString be null.
-
If serviceWorkerAllowed is null, then:
-
Set maxScopeString to "
/
" concatenated with the strings, except the last string that denotes the script’s file name, in job ’s script url 's path (including empty strings), separated from each other by "/
".
-
-
Else:
-
Let maxScope be the result of parsing serviceWorkerAllowed with job ’s script url .
-
Set maxScopeString to "
/
" concatenated with the strings in maxScope ’s path (including empty strings), separated from each other by "/
".
-
-
Let scopeString be "
/
" concatenated with the strings in scopeURL ’s path (including empty strings), separated from each other by "/
". -
If scopeString starts with maxScopeString , do nothing.
-
Else:
-
Invoke Reject Job Promise with job and a "
SecurityError
" exception. -
Asynchronously complete these steps with a network error .
-
-
If response ’s cache state is not "
local
", set registration ’s last update check time to the current time.The response’s cache state concept had been removed from fetch. The fetch issue #376 tracks the request to restore the concept or add some similar way to check this state.
-
Return true.
If the algorithm asynchronously completes with null, then:
-
Invoke Reject Job Promise with job and a
TypeError
.Note: This will do nothing if Reject Job Promise was previously invoked with a "
SecurityError
" exception. -
If newestWorker is null, invoke Clear Registration algorithm passing registration as its argument.
-
Invoke Finish Job with job and abort these steps.
Else, continue the rest of these steps after the algorithm’s asynchronous completion, with script being the asynchronous completion value.
-
"
-
If newestWorker is not null, newestWorker ’s script url equals job ’s script url with the exclude fragments flag set, and script ’s source text is a byte-for-byte match with newestWorker ’s script resource 's source text , if script is a classic script , and script ’s module record 's [[ECMAScriptCode]] is a byte-for-byte match with newestWorker ’s script resource 's module record 's [[ECMAScriptCode]] otherwise, then:
-
Invoke Resolve Job Promise with job and the
ServiceWorkerRegistration
object which represents registration . -
Invoke Finish Job with job and abort these steps.
-
-
Else:
-
Let worker be a new service worker .
-
Generate a unique opaque string and set worker ’s id to the value.
-
Set worker ’s script url to job ’s script url , worker ’s script resource to script , and worker ’s type to job ’s worker type .
-
Set worker ’s script resource ’s HTTPS state to httpsState .
-
Set worker ’s script resource ’s referrer policy to referrerPolicy .
-
Invoke Run Service Worker algorithm given worker , and with the force bypass cache for importscripts flag set if job ’s force bypass cache flag is set.
-
If an uncaught runtime script error occurs during the above step, then:
-
Invoke Reject Job Promise with job and a
TypeError
. -
If newestWorker is null, invoke Clear Registration algorithm passing registration as its argument.
-
Invoke Finish Job with job and abort these steps.
-
-
-
Invoke Install algorithm with job , worker , and registration as its arguments.
Soft Update
The user agent may call this as often as it likes to check for updates.
- Input
-
registration , a service worker registration
force bypass cache flag , an optional flag unset by default
Note: Implementers may use the force bypass cache flag to aid debugging (e.g. invocations from developer tools), and other specifications that extend service workers may also use the flag on their own needs.
- Output
-
None
-
Let newestWorker be the result of running Get Newest Worker algorithm passing registration as its argument.
-
If newestWorker is null, abort these steps.
-
Let job be the result of running Create Job with update , registration ’s scope url , newestWorker ’s script url , null, and null.
-
Set job ’s worker type to newestWorker ’s type .
-
Set job ’s force bypass cache flag if its force bypass cache flag is set.
-
Invoke Schedule Job with job .
Install
- Input
-
job , a job
worker , a service worker
registration , a service worker registration
- Output
-
none
-
Let installFailed be false.
-
Let newestWorker be the result of running Get Newest Worker algorithm passing registration as its argument.
-
Let redundantWorker be null.
-
Run the Update Registration State algorithm passing registration , "
installing
" and worker as the arguments. -
Run the Update Worker State algorithm passing registration ’s installing worker and installing as the arguments.
-
Assert: job ’s job promise is not null.
-
Invoke Resolve Job Promise with job and the
ServiceWorkerRegistration
object which represents registration . -
Queue a task to fire an event named
updatefound
at all theServiceWorkerRegistration
objects for all theservice workerclients whose creation URL matches registration ’s scope url and all the service workers whose containing service worker registration is registration . -
Let installingWorker be registration ’s installing worker .
-
Invoke Run Service Worker algorithm given installingWorker , and with the force bypass cache for importscripts flag set if job ’s force bypass cache flag is set.
-
Queue a task task to run the following substeps:
-
Let e be the result of creating an event with
InstallEvent
. -
Dispatch e at installingWorker ’s global object .
-
WaitForAsynchronousExtensions : Run the following substeps in parallel :
-
Wait until e ’s pending promises count is zero.
-
If the result of waiting for all of e ’s extend lifetime promises rejected, set installFailed to true.
-
If task is discarded or the script has been aborted by the termination of installingWorker , set installFailed to true.
-
-
Wait for task to have executed or been discarded.
-
Wait for the step labeled WaitForAsynchronousExtensions to complete.
-
If installFailed is true, then:
-
Set redundantWorker to registration ’s installing worker .
-
Run the Update Registration State algorithm passing registration , "
installing
" and null as the arguments. -
Run the Update Worker State algorithm passing redundantWorker and redundant as the arguments.
-
If newestWorker is null, invoke Clear Registration algorithm passing registration as its argument.
-
Invoke Finish Job with job and abort these steps.
-
-
Set registration ’s installing worker ’s imported scripts updated flag .
-
If registration ’s waiting worker is not null, then:
-
Set redundantWorker to registration ’s waiting worker .
-
Terminate redundantWorker .
-
The user agent may abort in-flight requests triggered by redundantWorker .
-
-
Run the Update Registration State algorithm passing registration , "
waiting
" and registration ’s installing worker as the arguments. -
Run the Update Registration State algorithm passing registration , "
installing
" and null as the arguments. -
Run the Update Worker State algorithm passing registration ’s waiting worker and installed as the arguments.
-
If redundantWorker is not null, run the Update Worker State algorithm passing redundantWorker and redundant as the arguments.
-
Invoke Finish Job with job .
-
Wait for all the tasks queued by Update Worker State invoked in this algorithm have executed.
-
Wait until no
service workerclient is using registration or registration ’s waiting worker ’s skip waiting flag is set. -
If registration ’s waiting worker is not null, invoke Activate algorithm with registration as its argument.
Activate
- Input
-
registration , a service worker registration
- Output
-
None
-
If registration ’s waiting worker is null, abort these steps.
-
Let redundantWorker be null.
-
If registration ’s active worker is not null, then:
-
Set redundantWorker to registration ’s active worker .
-
Wait for redundantWorker to finish handling any in-progress requests.
-
Terminate redundantWorker .
-
-
Run the Update Registration State algorithm passing registration , "
active
" and registration ’s waiting worker as the arguments. -
Run the Update Registration State algorithm passing registration , "
waiting
" and null as the arguments. -
Run the Update Worker State algorithm passing registration ’s active worker and activating as the arguments.
Note: Once an active worker is activating, neither a runtime script error nor a force termination of the active worker prevents the active worker from getting activated.
-
If redundantWorker is not null, run the Update Worker State algorithm passing redundantWorker and redundant as the arguments.
-
For each
service workerclient client whose creation URL matches registration ’s scope url :-
If client is a window client , unassociate client ’s responsible document from its application cache , if it has one.
-
Else if client is a shared worker client , unassociate client ’s global object from its application cache , if it has one.
Note: Resources will now use the service worker registration instead of the existing application cache.
-
-
For each
service workerclient client who is using registration :-
Set client ’s active worker to registration ’s active worker .
-
Invoke Notify Controller Change algorithm with client as the argument.
-
-
Let activeWorker be registration ’s active worker .
-
Invoke Run Service Worker algorithm with activeWorker as the argument.
-
Queue a task task to run the following substeps:
-
Let e be the result of creating an event with
ExtendableEvent
. -
Dispatch e at activeWorker ’s global object .
-
WaitForAsynchronousExtensions : Wait, in parallel , until e ’s pending promises count is zero.
-
-
Wait for task to have executed or been discarded, or the script to have been aborted by the termination of activeWorker .
-
Wait for the step labeled WaitForAsynchronousExtensions to complete.
-
Run the Update Worker State algorithm passing registration ’s active worker and activated as the arguments.
Run Service Worker
- Input
-
serviceWorker , a service worker
force bypass cache for importscripts flag , an optional flag unset by default
- Output
-
None
-
Let script be serviceWorker ’s script resource .
-
Assert: script is not null.
-
If serviceWorker is already running, abort these steps.
-
Create a separate parallel execution environment (i.e. a separate thread or process or equivalent construct), and run the rest of these steps in that context.
-
Call the JavaScript InitializeHostDefinedRealm() abstract operation with the following customizations:
-
For the global object, create a new
ServiceWorkerGlobalScope
object. Let workerGlobalScope be the created object. -
Let realmExecutionContext be the created JavaScript execution context .
-
-
Set serviceWorker ’s global object to workerGlobalScope .
-
Let workerEventLoop be a newly created event loop .
-
Let settingsObject be a new environment settings object whose algorithms are defined as follows:
- The realm execution context
-
Return realmExecutionContext .
- The global object
-
Return workerGlobalScope .
- The responsible event loop
-
Return workerEventLoop .
- The referrer policy
-
Return workerGlobalScope ’s referrer policy .
- The API URL character encoding
-
Return UTF-8.
- The API base URL
-
Return serviceWorker ’s script url .
- The origin
- The creation URL
-
Return workerGlobalScope ’s url .
- The HTTPS state
-
Return workerGlobalScope ’s HTTPS state .
-
Set workerGlobalScope ’s url to serviceWorker ’s script url .
-
Set workerGlobalScope ’s HTTPS state to serviceWorker ’s script resource ’s HTTPS state .
-
Set workerGlobalScope ’s referrer policy to serviceWorker ’s script resource ’s referrer policy .
-
Set workerGlobalScope ’s force bypass cache for importscripts flag if its force bypass cache for importscripts flag is set.
-
Create a new
WorkerLocation
object and associate it with workerGlobalScope . -
If serviceWorker is an active worker , and there are any tasks queued in serviceWorker ’s containing service worker registration ’s task queues , queue them to serviceWorker ’s event loop ’s task queues in the same order using their original task sources .
-
If script is a classic script , then run the classic script script . Otherwise, it is a module script ; run the module script script .
Note: In addition to the usual possibilities of returning a value or failing due to an exception, this could be prematurely aborted by the kill a worker or terminate a worker algorithms.
-
If script ’s has ever been evaluated flag is unset, then:
-
For each eventType of settingsObject ’s global object 's associated list of event listeners ' event types:
-
Append eventType to workerGlobalScope ’s associated service worker 's set of event types to handle .
-
Note: If the global object’s associated list of event listeners does not have any event listener added at this moment, the service worker’s set of event types to handle remains an empty set. The user agents are encouraged to show a warning that the event listeners must be added on the very first evaluation of the worker script.
-
Set script ’s has ever been evaluated flag .
-
-
Run the responsible event loop specified by settingsObject until it is destroyed.
-
Empty workerGlobalScope ’s list of active timers .
Terminate Service Worker
- Input
-
serviceWorker , a service worker
- Output
-
None
-
If serviceWorker is not running, abort these steps.
-
Let serviceWorkerGlobalScope be serviceWorker ’s global object .
-
Set serviceWorkerGlobalScope ’s closing flag to true.
-
If there are any tasks , whose task source is either the handle fetch task source or the handle functional event task source , queued in serviceWorkerGlobalScope ’s event loop ’s task queues , queue them to serviceWorker ’s containing service worker registration ’s corresponding task queues in the same order using their original task sources , and discard all the tasks (including tasks whose task source is neither the handle fetch task source nor the handle functional event task source ) from serviceWorkerGlobalScope ’s event loop ’s task queues without processing them.
Note: This effectively means that the fetch events and the other functional events such as push events are backed up by the registration’s task queues while the other tasks including message events are discarded.
-
Abort the script currently running in serviceWorker .
Handle Fetch
The Handle Fetch algorithm is the entry point for the fetch handling handed to the service worker context.
-
Let handleFetchFailed be false.
-
Let respondWithEntered be false.
-
Let eventCanceled be false.
-
Let r be a new
Request
object associated with request . -
Let headersObject be r ’s
headers
attribute value. -
Set headersObject ’s guard to immutable .
-
Let response be null.
-
Let registration be null.
-
Let client be request ’s client .
-
Let reservedClient be request ’s reserved client .
-
Let preloadResponse be a new promise .
-
Assert: request ’s destination is not "
serviceworker
". -
If request is a potential-navigation-or-subresource request , then:
-
Return null.
-
-
Else if request is a non-subresource request , then:
Note: If the non-subresource request is under the scope of a service worker registration, application cache is completely bypassed regardless of whether the non-subresource request uses the service worker registration.
-
If reservedClient is not null and is an environment settings object , then:
-
If reservedClient is not a secure context , return null.
-
-
Else:
-
If request ’s url is not a potentially trustworthy URL , return null.
-
-
If request is a navigation request and the navigation triggering it was initiated with a shift+reload or equivalent, return null.
-
Set registration to the result of running Match Service Worker Registration algorithm passing request ’s url as the argument.
-
If registration is null or registration ’s active worker is null, return null.
-
If request ’s destination is not
"report"
, set reservedClient ’s active service worker to registration ’s active worker . -
If request is a navigation request , registration ’s navigation preload enabled flag is set, request ’s method is `
GET
`, and registration ’s active worker 's set of event types to handle containsfetch
, then:Note: If the above is true except registration ’s active worker 's set of event types to handle does not contain
fetch
, then the user agent may wish to show a console warning, as the developer’s intent isn’t clear.-
Let preloadRequest be the result of cloning the request request .
-
Let preloadRequestHeaders be preloadRequest ’s header list .
-
Let preloadResponseObject be a new
Response
object associated with a newHeaders
object whose guard is "immutable
". -
Append to preloadRequestHeaders a new header whose name is `
Service-Worker-Navigation-Preload
` and value is registration ’s navigation preload header value . -
Set preloadRequest ’s skip-service-worker flag .
-
Run the following substeps in parallel :
-
Fetch preloadRequest .
To process response for navigationPreloadResponse , run these substeps:
-
If navigationPreloadResponse ’s type is "
error
", reject preloadResponse with aTypeError
and terminate these substeps. -
Associate preloadResponseObject with navigationPreloadResponse .
-
Resolve preloadResponse with navigationPreloadResponse .
-
-
-
-
Else, resolve preloadResponse with undefined.
Note: From this point, the
service workerclient starts to use its active service worker ’s containing service worker registration . -
-
Else if request is a subresource request , then:
-
If client ’s active service worker is non-null, set registration to client ’s active service worker ’s containing service worker registration .
-
Else, return null.
-
-
Let activeWorker be registration ’s active worker .
-
If activeWorker ’s set of event types to handle does not contain
fetch
, then:-
Return null and continue running these steps in parallel .
-
If request is a non-subresource request , or request is a subresource request and the time difference in seconds calculated by the current time minus registration ’s last update check time is greater than 86400, invoke Soft Update algorithm with registration .
-
Abort these steps.
Note: To avoid unnecessary delays, the Handle Fetch enforces early return when no event listeners have been deterministically added in the service worker’s global during the very first script execution.
-
-
If activeWorker ’s state is activating , wait for activeWorker ’s state to become activated .
-
Invoke Run Service Worker algorithm with activeWorker as the argument.
-
Queue a task task to run the following substeps:
-
Let e be the result of creating an event with
FetchEvent
. -
Initialize e ’s
cancelable
attribute to true. -
Initialize e ’s
request
attribute to r . -
Initialize e ’s
preloadResponse
to preloadResponse . -
If request is a non-subresource request and request ’s destination is not
"report"
, initialize e ’sreservedClientId
attribute to reservedClient ’s id , and to the empty string otherwise. -
If request is a navigation request , initialize e ’s
targetClientId
attribute to request ’s target client id , and to the empty string otherwise. -
Dispatch e at activeWorker ’s global object .
-
If e ’s respond-with entered flag is set, set respondWithEntered to true.
-
If e ’s wait to respond flag is set, then:
-
Wait until e ’s wait to respond flag is unset.
-
If e ’s respond-with error flag is set, set handleFetchFailed to true.
-
Else, set response to e ’s potential response .
-
-
If e ’s canceled flag is set, set eventCanceled to true.
If task is discarded or the script has been aborted by the termination of activeWorker , set handleFetchFailed to true.
The task must use activeWorker ’s event loop and the handle fetch task source .
-
-
Wait for task to have executed or been discarded.
-
If respondWithEntered is false, then:
-
If eventCanceled is true, return a network error and continue running these steps in parallel .
-
Else, return null and continue running these steps in parallel .
-
If request is a non-subresource request , or request is a subresource request and the time difference in seconds calculated by the current time minus registration ’s last update check time is greater than 86400, invoke Soft Update algorithm with registration .
-
Abort these steps.
-
-
If handleFetchFailed is true, then:
-
Return a network error and continue running these steps in parallel .
-
If request is a non-subresource request , or request is a subresource request and the time difference in seconds calculated by the current time minus registration ’s last update check time is greater than 86400, invoke Soft Update algorithm with registration .
-
-
Else:
-
Return response and continue running these steps in parallel .
-
If request is a non-subresource request , or request is a subresource request and the time difference in seconds calculated by the current time minus registration ’s last update check time is greater than 86400, invoke Soft Update algorithm with registration .
-
Handle Foreign Fetch
The Handle Foreign Fetch algorithm is the entry point for the fetch handling handed to the service worker context to handle foreign fetch requests.
-
Let handleFetchFailed be false.
-
Let respondWithEntered be false.
-
Let eventCanceled be false.
-
If request is not a subresource request , return null and abort these steps.
Note: Foreign fetch only allows intercepting of subresource requests. Navigation requests can be intercepted by the regular fetch event anyway, so there is no benefit to supporting those requests here as well.
-
If request ’s client is not a secure context , return null and abort these steps.
-
Let activeWorker be the result of running the Match Service Worker for Foreign Fetch algorithm passing request ’s url as the argument.
-
If activeWorker is null, return null.
-
If activeWorker ’s state is activating , then:
-
Wait for activeWorker ’s state to become activated .
-
-
If activeWorker ’s origin is the same as request ’s origin , return null.
-
Let originMatches be false.
-
If activeWorker ’s list of foreign fetch origins is empty, set originMatches to true.
-
For each origin in activeWorker ’s list of foreign fetch origins :
-
If origin is equal to request ’s origin , set originMatches to true.
-
-
If originMatches is false, return null.
-
If request ’s method is not a CORS-safelisted method , or if there is at least one header in request ’s header list for whose name is not a CORS-safelisted request-header , return null.
Note: In the future this might be relaxed by adding supported methods and headers to the
ForeignFetchOptions
. -
Let r be a new
Request
object associated with request . -
Invoke Run Service Worker algorithm with activeWorker as the argument.
-
Queue a task task to run the following substeps:
-
Let e be the result of creating an event with
ForeignFetchEvent
. -
Initialize e ’s
type
attribute toforeignfetch
. -
Initialize e ’s
cancelable
attribute to true. -
Initialize e ’s
request
attribute to r . -
Initialize e ’s
origin
attribute to the Unicode serialization of request ’s origin . -
Dispatch e at activeWorker ’s global object .
-
If e ’s respond-with entered flag is set, set respondWithEntered to true.
-
If e ’s wait to respond flag is set, wait until e ’s wait to respond flag is unset.
-
Let internalResponse be e ’s potential response .
-
If internalResponse is a filtered response , set internalResponse to internalResponse ’s internal response .
-
If e ’s respond-with error flag is set, set handleFetchFailed to true.
-
Else if e ’s origin is null:
-
If e ’s list of exposed headers is not empty, set handleFetchFailed to true.
-
Else if e ’s potential response is a opaque-redirect filtered response , set response to e ’s potential response .
-
Else set response to an opaque filtered response of internalResponse .
-
-
Else if e ’s origin is not equal to the Unicode serialization of request ’s origin , set handleFetchFailed to true.
-
Else if e ’s potential response is an opaque filtered response or is an opaque-redirect filtered response , set response to e ’s potential response .
-
Else if request ’s response tainting is
"opaque"
, set response to an opaque filtered response of internalResponse . -
Else:
-
Let headers be e ’s list of exposed headers .
-
If response is a CORS filtered response , remove from internalResponse ’s CORS-exposed header-name list all values not in headers .
-
Else set internalResponse ’s CORS-exposed header-name list to headers .
-
Set response to a CORS filtered response of internalResponse .
-
-
If e ’s canceled flag is set, set eventCanceled to true.
If task is discarded or the script has been aborted by the termination of activeWorker , set handleFetchFailed to true.
The task must use activeWorker ’s event loop and the handle fetch task source .
-
-
Wait for task to have executed or been discarded.
-
If respondWithEntered is false, then:
-
If eventCanceled is true, then:
-
Return a network error .
-
-
Else:
-
Return null.
-
-
-
If handleFetchFailed is true, then:
-
Return a network error .
-
-
Else:
-
Return response .
-
Handle Functional Event
- Input
-
event , an
ExtendableEvent
objectregistration , a service worker registration
callbackSteps , an algorithm
- Output
-
None
-
Assert: scope to registration map contains a value equal to registration .
-
Assert: registration ’s active worker is not null.
-
Let activeWorker be registration ’s active worker .
-
If activeWorker ’s set of event types to handle does not contain event ’s
type
, then:-
Return and continue running these steps in parallel .
-
If the time difference in seconds calculated by the current time minus registration ’s last update check time is greater than 86400, invoke Soft Update algorithm with registration .
-
Abort these steps.
Note: To avoid unnecessary delays, the Handle Functional Event enforces early return when no event listeners have been deterministically added in the service worker’s global during the very first script execution.
-
-
If activeWorker ’s state is activating , wait for activeWorker ’s state to become activated .
-
Invoke Run Service Worker algorithm with activeWorker as the argument.
-
Queue a task task to run these substeps:
-
Invoke callbackSteps with activeWorker ’s global object as its argument.
The task must use activeWorker ’s event loop and the handle functional event task source .
-
-
Wait for task to have executed or been discarded.
-
If the time difference in seconds calculated by the current time minus registration ’s last update check time is greater than 86400, invoke Soft Update algorithm with registration .
Handle
Service
Worker
Client
Unload
The
user
agent
must
run
these
steps
when
a
service
worker
client
unloads
by
unloading
,
being
killed
,
or
terminating
.
- Input
-
client , a
service workerclient - Output
-
None
-
Run the following steps atomically.
-
Let registration be the service worker registration used by client .
-
If registration is null, abort these steps.
-
If any other
service workerclient is using registration , abort these steps. -
If registration ’s uninstalling flag is set, invoke Clear Registration algorithm passing registration as its argument and abort these steps.
-
If registration ’s waiting worker is not null, run Activate algorithm with registration as the argument.
Handle User Agent Shutdown
- Input
-
None
- Output
-
None
-
For each scope → registration of scope to registration map :
-
If registration ’s installing worker installingWorker is not null, then:
-
If the result of running Get Newest Worker with registration is installingWorker , invoke Clear Registration with registration and continue to the next iteration of the loop.
-
Else, set registration ’s installing worker to null.
-
-
If registration ’s waiting worker is not null, run the following substep in parallel :
-
Invoke Activate with registration .
-
-
Unregister
- Input
-
job , a job
- Output
-
none
-
If the origin of job ’s scope url is not job ’s client 's origin , then:
-
Invoke Reject Job Promise with job and a "
SecurityError
" exception. -
Invoke Finish Job with job and abort these steps.
-
-
Let registration be the result of running Get Registration algorithm passing job ’s scope url as the argument.
-
If registration is null, then:
-
Invoke Resolve Job Promise with job and false.
-
Invoke Finish Job with job and abort these steps.
-
-
Set registration ’s uninstalling flag .
-
Invoke Resolve Job Promise with job and true.
-
If no
service workerclient is using registration , invoke Clear Registration algorithm passing registration as its argument.Note: When the registration is being used for a client, the deletion of the registration is handled by the Handle
Service WorkerClient Unload algorithm. -
Invoke Finish Job with job .
Set Registration
- Input
-
scope , a URL
useCache , a boolean
- Output
-
registration , a service worker registration
-
Run the following steps atomically.
-
Let scopeString be serialized scope with the exclude fragment flag set.
-
Let registration be a new service worker registration whose scope url is set to scope and use cache is set to useCache .
-
Set scope to registration map [ scopeString ] to registration .
-
Return registration .
Clear Registration
- Input
-
registration , a service worker registration
- Output
-
None
-
Run the following steps atomically.
-
Let redundantWorker be null.
-
If registration ’s installing worker is not null, then:
-
Set redundantWorker to registration ’s installing worker .
-
Terminate redundantWorker .
-
The user agent may abort in-flight requests triggered by redundantWorker .
-
Run the Update Registration State algorithm passing registration , "
installing
" and null as the arguments. -
Run the Update Worker State algorithm passing redundantWorker and redundant as the arguments.
-
-
If registration ’s waiting worker is not null, then:
-
Set redundantWorker to registration ’s waiting worker .
-
Terminate redundantWorker .
-
The user agent may abort in-flight requests triggered by redundantWorker .
-
Run the Update Registration State algorithm passing registration , "
waiting
" and null as the arguments. -
Run the Update Worker State algorithm passing redundantWorker and redundant as the arguments.
-
-
If registration ’s active worker is not null, then:
-
Set redundantWorker to registration ’s active worker .
-
Terminate redundantWorker .
-
The user agent may abort in-flight requests triggered by redundantWorker .
-
Run the Update Registration State algorithm passing registration , "
active
" and null as the arguments. -
Run the Update Worker State algorithm passing redundantWorker and redundant as the arguments.
-
-
Let scopeString be serialized registration ’s scope url with the exclude fragment flag set.
-
Remove scope to registration map [ scopeString ].
Update Registration State
- Input
-
registration , a service worker registration
target , a string (one of "
installing
", "waiting
", and "active
")source , a service worker or null
- Output
-
None
-
Let registrationObjects be an array containing all the
ServiceWorkerRegistration
objects associated with registration . -
If target is "
installing
", then:-
Set registration ’s installing worker to source .
-
For each registrationObject in registrationObjects :
-
Queue a task to set the
installing
attribute of registrationObject to theServiceWorker
object that represents registration ’s installing worker , or null if registration ’s installing worker is null.
-
-
-
Else if target is "
waiting
", then:-
Set registration ’s waiting worker to source .
-
For each registrationObject in registrationObjects :
-
Queue a task to set the
waiting
attribute of registrationObject to theServiceWorker
object that represents registration ’s waiting worker , or null if registration ’s waiting worker is null.
-
-
-
Else if target is "
active
", then:-
Set registration ’s active worker to source .
-
For each registrationObject in registrationObjects :
-
Queue a task to set the
active
attribute of registrationObject to theServiceWorker
object that represents registration ’s active worker , or null if registration ’s active worker is null.
-
The task must use registrationObject ’s relevant settings object ’s responsible event loop and the DOM manipulation task source .
-
Update Worker State
- Input
-
worker , a service worker
state , a service worker 's state
- Output
-
None
-
Set worker ’s state to state .
-
Let workerObjects be an array containing all the
ServiceWorker
objects associated with worker . -
For each workerObject in workerObjects :
-
Queue a task to run these substeps:
-
Set the
state
attribute of workerObject to the value (inServiceWorkerState
enumeration) corresponding to the first matching statement, switching on worker ’s state :- installing
-
Note: The service worker in this state is considered an installing worker . During this state,
waitUntil()
can be called inside theoninstall
event handler to extend the life of the installing worker until the passed promise resolves successfully. This is primarily used to ensure that the service worker is not active until all of the core caches are populated. - installed
-
Note: The service worker in this state is considered a waiting worker .
- activating
-
Note: The service worker in this state is considered an active worker . During this state,
waitUntil()
can be called inside theonactivate
event handler to extend the life of the active worker until the passed promise resolves successfully. No functional events are dispatched until the state becomes activated . - activated
-
Note: The service worker in this state is considered an active worker ready to handle functional events .
- redundant
-
Note: A new service worker is replacing the current service worker , or the current service worker is being discarded due to an install failure.
-
Fire an event named
statechange
at workerObject .
-
The task must use workerObject ’s relevant settings object ’s responsible event loop and the DOM manipulation task source .
-
Notify Controller Change
- Input
-
client , a
service workerclient - Output
-
None
-
Assert: client is not null.
-
If client is a type of environment settings object , queue a task to fire an event named
controllerchange
at theServiceWorkerContainer
object client is associated with.
The task must use client ’s responsible event loop and the DOM manipulation task source .
Match Service Worker Registration
- Input
-
clientURL , a URL
- Output
-
registration , a service worker registration
-
Run the following steps atomically.
-
Let clientURLString be serialized clientURL .
-
Let matchingScope be the empty string.
-
Let allScopes be the result of getting the keys from scope to registration map .
-
Set matchingScope to the longest value in allScopes which the value of clientURLString starts with, if it exists.
Note: The URL string matching in this step is prefix-based rather than path-structural (e.g. a client URL string with "/prefix-of/resource.html" will match a registration for a scope with "/prefix").
-
Let parsedMatchingScope be null.
-
If matchingScope is not the empty string, set parsedMatchingScope to the result of parsing matchingScope .
-
Let registration be the result of running Get Registration algorithm passing parsedMatchingScope as the argument.
-
If registration is not null and registration ’s uninstalling flag is set, return null.
-
Return registration .
Match Service Worker for Foreign Fetch
- Input
-
requestURL , a URL
- Output
-
worker , a service worker
-
Run the following steps atomically.
-
Let registration be the result of running the Match Service Worker Registration algorithm passing requestURL as the argument.
-
If registration is null, return null.
-
Let worker be registration ’s active worker .
-
If worker is null, return null.
-
Let requestURLString be the serialized requestURL .
-
For each URL scope in worker ’s list of foreign fetch scopes :
-
Let scopeString be the serialized scope .
-
If requestURLString starts with scopeString return worker .
-
-
Return null.
Get Registration
- Input
-
scope , a URL
- Output
-
registration , a service worker registration
-
Run the following steps atomically.
-
Let scopeString be the empty string.
-
If scope is not null, set scopeString to serialized scope with the exclude fragment flag set.
-
Let registration be null.
-
For each key → value of scope to registration map :
-
If scopeString matches key , set registration to value .
-
-
Return registration .
Get Newest Worker
- Input
-
registration , a service worker registration
- Output
-
newestWorker , a service worker
-
Run the following steps atomically.
-
Let newestWorker be null.
-
If registration ’s installing worker is not null, set newestWorker to registration ’s installing worker .
-
Else if registration ’s waiting worker is not null, set newestWorker to registration ’s waiting worker .
-
Else if registration ’s active worker is not null, set newestWorker to registration ’s active worker .
-
Return newestWorker .
Create Client
-
Let clientObject be a new
Client
object. -
Set clientObject ’s
service workerclient to client . -
Set clientObject ’s reserved state to true if client ’s execution ready flag is unset, and false otherwise.
-
Return clientObject .
Create Window Client
- Input
-
client , a
service workerclientvisibilityState , a string
focusState , a boolean
ancestorOrigins , an array
- Output
-
windowClient , a
WindowClient
object
-
Let windowClient be a new
WindowClient
object. -
Set windowClient ’s
service workerclient to client . -
Set windowClient ’s visibility state to visibilityState .
-
Set windowClient ’s focus state to focusState .
-
Set windowClient ’s ancestor origins array to ancestorOrigins .
-
Return windowClient .
Query Cache
- Input
-
request , a
Request
objectoptions , a
CacheQueryOptions
object, optionaltargetStorage , an array that has [
Request
,Response
] pairs as its elements, optional - Output
-
resultArray , an array that has [
Request
,Response
] pairs as its elements
-
Let requestArray be an empty array.
-
Let responseArray be an empty array.
-
Let resultArray be an empty array.
-
If options .
ignoreMethod
is false and request .method is not `GET
`, return resultArray . -
Let cachedURL and requestURL be null.
-
If the optional argument targetStorage is omitted, then:
-
For each fetching record entry of its request to response map , in key insertion order:
-
-
Else:
-
For each record in targetStorage :
-
If options .
ignoreSearch
is true, then: -
If cachedURL equals requestURL with the exclude fragments flag set, then:
-
Add record [0] to requestArray .
-
Add record [1] to responseArray .
-
-
-
For each cachedResponse in responseArray with the index index :
-
Let cachedRequest be the index th element in requestArray .
-
If cachedResponse ’s response 's header list contains no header named `
Vary
`, or options .ignoreVary
is true, then:-
Add an array [ cachedRequest , cachedResponse ] to resultArray .
-
Continue to the next iteration of the loop.
-
-
Let varyHeaders be the array containing the elements corresponding to the field-values of the Vary header.
-
Let matchFailed be false.
-
For each f in varyHeaders :
-
If matchFailed is false, add an array [ cachedRequest , cachedResponse ] to resultArray .
-
-
Return resultArray .
Batch Cache Operations
- Input
-
operations , an array of
CacheBatchOperation
dictionary objects - Output
-
promise , a promise resolves with an array of
Response
objects
-
Let promise be a promise resolved with no value.
-
Return the result of transforming promise with a fulfillment handler that performs the following substeps in parallel :
-
Let itemsCopy be a new request to response map that is a copy of its context object ’s request to response map .
-
Let addedRecords be an empty array.
-
Try running the following substeps atomically:
-
Let resultArray be an empty array.
-
For each operation in operations :
-
If operation .
type
matches neither "delete" nor "put", throw aTypeError
. -
If operation .
type
matches "delete" and operation .response
is not null, throw aTypeError
. -
If the result of running Query Cache algorithm passing operation .
request
, operation .options
, and addedRecords as the arguments is not an empty array, throw an "InvalidStateError
" exception. -
Let requestResponseArray be the result of running Query Cache algorithm passing operation .
request
and operation .options
as the arguments. -
For each requestResponse in requestResponseArray :
-
If operation .
type
matches "delete", remove the corresponding fetching record from request to response map .
-
-
If operation .
type
matches "put", then:-
If r ’s url 's scheme is not one of "
http
" and "https
", throw aTypeError
. -
Set requestResponseArray to the result of running Query Cache algorithm passing operation .
request
. -
If requestResponseArray is not an empty array, then:
-
Let requestResponse be requestResponseArray [0].
-
Let fetchingRecord be the corresponding fetching record for requestResponse [0] and requestResponse [1] in request to response map .
-
Set fetchingRecord .[[key]] to operation .
request
and fetchingRecord .[[value]] to operation .response
.
-
-
Else:
-
Set a newly-created fetching record {[[key]]: operation .
request
, [[value]]: operation .response
} to request to response map .
Note: The cache commit is allowed as long as the response’s headers are available.
-
-
If the cache write operation in the previous two steps failed due to exceeding the granted quota limit, throw a "
QuotaExceededError
" exception. -
Add an array [ operation .request, operation .response] to addedRecords .
-
Add operation .response to resultArray .
-
-
Return resultArray .
-
-
And then, if an exception was thrown , then:
-
Set the context object ’s request to response map to itemsCopy .
-
Throw the exception
-
-
Appendix B: Extended HTTP headers
Service Worker Script Request
An HTTP request to fetch a service worker 's script resource will include the following header :
-
`
Service-Worker
` -
Indicates this request is a service worker 's script resource request.
Note: This header helps administrators log the requests and detect threats.
Service Worker Script Response
An HTTP response to a service worker 's script resource request can include the following header :
-
`
Service-Worker-Allowed
` -
Indicates the user agent will override the path restriction, which limits the maximum allowed scope url that the script can control , to the given value.
Note: The value is a URL. If a relative URL is given, it is parsed against the script’s URL.
// Maximum allowed scope defaults to the path the script sits in // "/js" in this example navigator. serviceWorker. register( "/js/sw.js" ). then(() => { console. log( "Install succeeded with the default scope '/js'." ); });
// Set the scope to an upper path of the script location // Response has no Service-Worker-Allowed header navigator. serviceWorker. register( "/js/sw.js" , { scope: "/" }). catch (() => { console. error( "Install failed due to the path restriction violation." ); });
// Set the scope to an upper path of the script location // Response included "Service-Worker-Allowed : /" navigator. serviceWorker. register( "/js/sw.js" , { scope: "/" }). then(() => { console. log( "Install succeeded as the max allowed scope was overriden to '/'." ); });
// Set the scope to an upper path of the script location // Response included "Service-Worker-Allowed : /foo" navigator. serviceWorker. register( "/foo/bar/sw.js" , { scope: "/" }). catch (() => { console. error( "Install failed as the scope is still out of the overriden maximum allowed scope." ); });
Syntax
ABNF for the values of the headers used by the service worker 's script resource requests and responses:
Service-Worker = %x73.63.72.69.70.74 ; "script", case-sensitive
Note: The validation of the Service-Worker-Allowed header’s values is done by URL parsing algorithm (in Update algorithm) instead of using ABNF.
9. Acknowledgements
Deep thanks go to Andrew Betts for organizing and hosting a small workshop of like-minded individuals including: Jake Archibald, Jackson Gabbard, Tobie Langel, Robin Berjon, Patrick Lauke, Christian Heilmann. From the clarity of the day’s discussions and the use-cases outlined there, much has become possible. Further thanks to Andrew for raising consciousness about the offline problem. His organization of EdgeConf and inclusion of Offline as a persistent topic there has created many opportunities and connections that have enabled this work to progress.
Anne van Kesteren has generously lent his encyclopedic knowledge of Web Platform arcana and standards development experience throughout the development of the service worker. This specification would be incomplete without his previous work in describing the real-world behavior of URLs, HTTP Fetch, Promises, and DOM. Similarly, this specification would not be possible without Ian Hickson’s rigorous Web Worker spec. Much thanks to him.
In no particular order, deep gratitude for design guidance and discussion goes to: Jungkee Song, Alec Flett, David Barrett-Kahn, Aaron Boodman, Michael Nordman, Tom Ashworth, Kinuko Yasuda, Darin Fisher, Jonas Sicking, Jesús Leganés Combarro, Mark Christian, Dave Hermann, Yehuda Katz, François Remy, Ilya Grigorik, Will Chan, Domenic Denicola, Nikhil Marathe, Yves Lafon, Adam Barth, Greg Simon, Devdatta Akhawe, Dominic Cooney, Jeffrey Yasskin, Joshua Bell, Boris Zbarsky, Matt Falkenhagen, Tobie Langel, Gavin Peters, Ben Kelly, Hiroki Nakagawa, Jake Archibald, Josh Soref, Jinho Bang, Yutaka Hirano, and Michael(tm) Smith.
Jason Weber, Chris Wilson, Paul Kinlan, Ehsan Akhgari, and Daniel Austin have provided valuable, well-timed feedback on requirements and the standardization process.
The authors would also like to thank Dimitri Glazkov for his scripts and formatting tools which have been essential in the production of this specification. The authors are also grateful for his considerable guidance.
Thanks also to Vivian Cromwell, Greg Simon, Alex Komoroske, Wonsuk Lee, and Seojin Kim for their considerable professional support.