Living Standard — Last Updated 14 March 2025
Support in all current engines.
This section is non-normative.
This specification defines an API for running scripts in the background independently of any user interface scripts.
This allows for long-running scripts that are not interrupted by scripts that respond to clicks or other user interactions, and allows long tasks to be executed without yielding to keep the page responsive.
Workers (as these background scripts are called herein) are relatively heavy-weight, and are not intended to be used in large numbers. For example, it would be inappropriate to launch one worker for each pixel of a four megapixel image. The examples below show some appropriate uses of workers.
Generally, workers are expected to be long-lived, have a high start-up performance cost, and a high per-instance memory cost.
This section is non-normative.
There are a variety of uses that workers can be put to. The following subsections show various examples of this use.
This section is non-normative.
The simplest use of workers is for performing a computationally expensive task without interrupting the user interface.
In this example, the main document spawns a worker to (naïvely) compute prime numbers, and progressively displays the most recently found prime number.
The main page is as follows:
EXAMPLE
workers/primes/page.html
The
Worker()
constructor
call
creates
a
worker
and
returns
a
Worker
object
representing
that
worker,
which
is
used
to
communicate
with
the
worker.
That
object's
onmessage
event
handler
allows
the
code
to
receive
messages
from
the
worker.
The worker itself is as follows:
EXAMPLE
workers/primes/worker.js
The
bulk
of
this
code
is
simply
an
unoptimized
search
for
a
prime
number.
The
postMessage()
method
is
used
to
send
a
message
back
to
the
page
when
a
prime
is
found.
This section is non-normative.
All
of
our
examples
so
far
show
workers
that
run
classic
scripts
.
Workers
can
instead
be
instantiated
using
module
scripts
,
which
have
the
usual
benefits:
the
ability
to
use
the
JavaScript
import
statement
to
import
other
modules;
strict
mode
by
default;
and
top-level
declarations
not
polluting
the
worker's
global
scope.
As
the
import
statement
is
available,
the
importScripts()
method
will
automatically
fail
inside
module
workers.
In this example, the main document uses a worker to do off-main-thread image manipulation. It imports the filters used from another module.
The main page is as follows:
EXAMPLE
workers/modules/page.html
The worker file is then:
EXAMPLE
workers/modules/worker.js
Which
imports
the
file
filters.js
:
EXAMPLE
workers/modules/filters.js
Support in all current engines.
This section is non-normative.
This section introduces shared workers using a Hello World example. Shared workers use slightly different APIs, since each worker can have multiple connections.
This first example shows how you connect to a worker and how a worker can send a message back to the page when it connects to it. Received messages are displayed in a log.
Here is the HTML page:
EXAMPLE
workers/shared/001/test.html
Here is the JavaScript worker:
EXAMPLE
workers/shared/001/test.js
This
second
example
extends
the
first
one
by
changing
two
things:
first,
messages
are
received
using
addEventListener()
instead
of
an
event
handler
IDL
attribute
,
and
second,
a
message
is
sent
to
the
worker,
causing
the
worker
to
send
another
message
in
return.
Received
messages
are
again
displayed
in
a
log.
Here is the HTML page:
EXAMPLE
workers/shared/002/test.html
Here is the JavaScript worker:
EXAMPLE
workers/shared/002/test.js
Finally,
the
example
is
extended
to
show
how
two
pages
can
connect
to
the
same
worker;
in
this
case,
the
second
page
is
merely
in
an
iframe
on
the
first
page,
but
the
same
principle
would
apply
to
an
entirely
separate
page
in
a
separate
top-level
traversable
.
Here is the outer HTML page:
EXAMPLE
workers/shared/003/test.html
Here is the inner HTML page:
EXAMPLE
workers/shared/003/inner.html
Here is the JavaScript worker:
EXAMPLE
workers/shared/003/test.js
This section is non-normative.
In this example, multiple windows (viewers) can be opened that are all viewing the same map. All the windows share the same map information, with a single worker coordinating all the viewers. Each viewer can move around independently, but if they set any data on the map, all the viewers are updated.
The main page isn't interesting, it merely provides a way to open the viewers:
EXAMPLE
workers/multiviewer/page.html
The viewer is more involved:
EXAMPLE
workers/multiviewer/viewer.html
There are several key things worth noting about the way the viewer is written.
Multiple listeners . Instead of a single message processing function, the code here attaches multiple event listeners, each one performing a quick check to see if it is relevant for the message. In this example it doesn't make much difference, but if multiple authors wanted to collaborate using a single port to communicate with a worker, it would allow for independent code instead of changes having to all be made to a single event handling function.
Registering
event
listeners
in
this
way
also
allows
you
to
unregister
specific
listeners
when
you
are
done
with
them,
as
is
done
with
the
configure()
method
in
this
example.
Finally, the worker:
EXAMPLE
workers/multiviewer/worker.js
Connecting
to
multiple
pages
.
The
script
uses
the
onconnect
event
listener
to
listen
for
multiple
connections.
Direct channels . When the worker receives a "msg" message from one viewer naming another viewer, it sets up a direct connection between the two, so that the two viewers can communicate directly without the worker having to proxy all the messages.
This section is non-normative.
With multicore CPUs becoming prevalent, one way to obtain better performance is to split computationally expensive tasks amongst multiple workers. In this example, a computationally expensive task that is to be performed for every number from 1 to 10,000,000 is farmed out to ten subworkers.
The main page is as follows, it just reports the result:
EXAMPLE
workers/multicore/page.html
The worker itself is as follows:
EXAMPLE
workers/multicore/worker.js
It consists of a loop to start the subworkers, and then a handler that waits for all the subworkers to respond.
The subworkers are implemented as follows:
EXAMPLE
workers/multicore/core.js
They receive two numbers in two events, perform the computation for the range of numbers thus specified, and then report the result back to the parent.
This section is non-normative.
Suppose that a cryptography library is made available that provides three tasks:
The library itself is as follows:
EXAMPLE
workers/crypto/libcrypto-v1.js
Note that the crypto functions here are just stubs and don't do real cryptography.
This library could be used as follows:
EXAMPLE
workers/crypto/page.html
A later version of the API, though, might want to offload all the crypto work onto subworkers. This could be done as follows:
EXAMPLE
workers/crypto/libcrypto-v2.js
The little subworkers would then be as follows.
For generating key pairs:
EXAMPLE
workers/crypto/libcrypto-v2-generator.js
For encrypting:
EXAMPLE
workers/crypto/libcrypto-v2-encryptor.js
For decrypting:
EXAMPLE
workers/crypto/libcrypto-v2-decryptor.js
Notice how the users of the API don't have to even know that this is happening — the API hasn't changed; the library can delegate to subworkers without changing its API, even though it is accepting data using message channels.
This section is non-normative.
Creating
a
worker
requires
a
URL
to
a
JavaScript
file.
The
Worker()
constructor
is
invoked
with
the
URL
to
that
file
as
its
only
argument;
a
worker
is
then
created
and
returned:
var
worker
=
new
Worker('helper.js');
If you want your worker script to be interpreted as a module script instead of the default classic script , you need to use a slightly different signature:
var
worker
=
new
Worker('helper.mjs',
{
type:
"module"
});
This section is non-normative.
Dedicated
workers
use
MessagePort
objects
behind
the
scenes,
and
thus
support
all
the
same
features,
such
as
sending
structured
data,
transferring
binary
data,
and
transferring
other
ports.
To
receive
messages
from
a
dedicated
worker,
use
the
onmessage
event
handler
IDL
attribute
on
the
Worker
object:
worker.onmessage
=
function
(event)
{
...
};
You
can
also
use
the
addEventListener()
method.
The
implicit
MessagePort
used
by
dedicated
workers
has
its
port
message
queue
implicitly
enabled
when
it
is
created,
so
there
is
no
equivalent
to
the
MessagePort
interface's
start()
method
on
the
Worker
interface.
To
send
data
to
a
worker,
use
the
postMessage()
method.
Structured
data
can
be
sent
over
this
communication
channel.
To
send
ArrayBuffer
objects
efficiently
(by
transferring
them
rather
than
cloning
them),
list
them
in
an
array
in
the
second
argument.
worker.postMessage({
operation: 'find-edges',
input: buffer, // an ArrayBuffer object
threshold: 0.6,
},
[buffer]);
To
receive
a
message
inside
the
worker,
the
onmessage
event
handler
IDL
attribute
is
used.
onmessage
=
function
(event)
{
...
};
You
can
again
also
use
the
addEventListener()
method.
In
either
case,
the
data
is
provided
in
the
event
object's
data
attribute.
To
send
messages
back,
you
again
use
postMessage()
.
It
supports
the
structured
data
in
the
same
manner.
postMessage(event.data.input,
[event.data.input]);
//
transfer
the
buffer
back
Support in all current engines.
This section is non-normative.
Shared workers are identified by the URL of the script used to create it, optionally with an explicit name. The name allows multiple instances of a particular shared worker to be started.
Shared workers are scoped by origin . Two different sites using the same names will not collide. However, if a page tries to use the same shared worker name as another page on the same site, but with a different script URL, it will fail.
Creating
shared
workers
is
done
using
the
SharedWorker()
constructor.
This
constructor
takes
the
URL
to
the
script
to
use
for
its
first
argument,
and
the
name
of
the
worker,
if
any,
as
the
second
argument.
var
worker
=
new
SharedWorker('service.js');
Communicating
with
shared
workers
is
done
with
explicit
MessagePort
objects.
The
object
returned
by
the
SharedWorker()
constructor
holds
a
reference
to
the
port
on
its
port
attribute.
worker.port.onmessage = function (event) { ... };
worker.port.postMessage('some message');
worker.port.postMessage({
foo:
'structured',
bar:
['data',
'also',
'possible']});
Inside
the
shared
worker,
new
clients
of
the
worker
are
announced
using
the
connect
event.
The
port
for
the
new
client
is
given
by
the
event
object's
source
attribute.
onconnect = function (event) {
var newPort = event.source;
// set up a listener
newPort.onmessage = function (event) { ... };
// send a message back to the port
newPort.postMessage('ready!'); // can also send structured data, of course
};
This standard defines two kinds of workers: dedicated workers, and shared workers. Dedicated workers, once created, are linked to their creator, but message ports can be used to communicate from a dedicated worker to multiple other browsing contexts or workers. Shared workers, on the other hand, are named, and once created any script running in the same origin can obtain a reference to that worker and communicate with it. Service Workers defines a third kind. [SW]
The global scope is the "inside" of a worker.
WorkerGlobalScope
common
interface
Support in all current engines.
[Exposed=Worker]
interface WorkerGlobalScope : EventTarget {
readonly attribute WorkerGlobalScope self;
readonly attribute WorkerLocation location;
readonly attribute WorkerNavigator navigator;
undefined importScripts((TrustedScriptURL
or USVString)... urls);
attribute OnErrorEventHandler onerror;
attribute EventHandler onlanguagechange;
attribute EventHandler onoffline;
attribute EventHandler ononline;
attribute EventHandler onrejectionhandled;
attribute EventHandler onunhandledrejection;
};
WorkerGlobalScope
serves
as
the
base
class
for
specific
types
of
worker
global
scope
objects,
including
DedicatedWorkerGlobalScope
,
SharedWorkerGlobalScope
,
and
ServiceWorkerGlobalScope
.
A
WorkerGlobalScope
object
has
an
associated
owner
set
(a
set
of
Document
and
WorkerGlobalScope
objects).
It
is
initially
empty
and
populated
when
the
worker
is
created
or
obtained.
It
is
a
set
,
instead
of
a
single
owner,
to
accommodate
SharedWorkerGlobalScope
objects.
A
WorkerGlobalScope
object
has
an
associated
type
("
classic
"
or
"
module
").
It
is
set
during
creation.
A
WorkerGlobalScope
object
has
an
associated
url
(null
or
a
URL
).
It
is
initially
null.
A
WorkerGlobalScope
object
has
an
associated
name
(a
string).
It
is
set
during
creation.
The
name
can
have
different
semantics
for
each
subclass
of
WorkerGlobalScope
.
For
DedicatedWorkerGlobalScope
instances,
it
is
simply
a
developer-supplied
name,
useful
mostly
for
debugging
purposes.
For
SharedWorkerGlobalScope
instances,
it
allows
obtaining
a
reference
to
a
common
shared
worker
via
the
SharedWorker()
constructor.
For
ServiceWorkerGlobalScope
objects,
it
doesn't
make
sense
(and
as
such
isn't
exposed
through
the
JavaScript
API
at
all).
A
WorkerGlobalScope
object
has
an
associated
policy
container
(a
policy
container
).
It
is
initially
a
new
policy
container
.
A
WorkerGlobalScope
object
has
an
associated
embedder
policy
(an
embedder
policy
).
A
WorkerGlobalScope
object
has
an
associated
module
map
.
It
is
a
module
map
,
initially
empty.
A
WorkerGlobalScope
object
has
an
associated
cross-origin
isolated
capability
boolean.
It
is
initially
false.
workerGlobal
.
self
Support in all current engines.
workerGlobal
.
location
Support in all current engines.
WorkerLocation
object.
workerGlobal
.
navigator
Support in all current engines.
WorkerNavigator
object.
workerGlobal
.
importScripts
(...
urls
)
WorkerGlobalScope/importScripts
Support in all current engines.
The
self
attribute
must
return
the
WorkerGlobalScope
object
itself.
The
location
attribute
must
return
the
WorkerLocation
object
whose
associated
WorkerGlobalScope
object
is
the
WorkerGlobalScope
object.
While
the
WorkerLocation
object
is
created
after
the
WorkerGlobalScope
object,
this
is
not
problematic
as
it
cannot
be
observed
from
script.
The
following
are
the
event
handlers
(and
their
corresponding
event
handler
event
types
)
that
must
be
supported,
as
event
handler
IDL
attributes
,
by
objects
implementing
the
WorkerGlobalScope
interface:
Event handler | Event handler event type |
---|---|
onerror
Support in all current engines.
Firefox
3.5+
Safari
4+
Chrome
4+
Opera 11.5+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 10+ Firefox Android ? Safari iOS 5+ Chrome Android ? WebView Android ? Samsung Internet ? Opera Android ? |
error
|
onlanguagechange
WorkerGlobalScope/languagechange_event Support in all current engines.
Firefox
74+
Safari
4+
Chrome
4+
Opera 11.5+ Edge 79+ Edge (Legacy) ? Internet Explorer No Firefox Android ? Safari iOS 5+ Chrome Android ? WebView Android 37+ Samsung Internet ? Opera Android ? |
languagechange
|
onoffline
WorkerGlobalScope/offline_event
Firefox
29+
Safari
8+
Chrome
No
Opera ? Edge No Edge (Legacy) ? Internet Explorer No Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android ? |
offline
|
ononline
WorkerGlobalScope/online_event
Firefox
29+
Safari
8+
Chrome
No
Opera ? Edge No Edge (Legacy) ? Internet Explorer No Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android ? |
online
|
onrejectionhandled
|
rejectionhandled
|
onunhandledrejection
|
unhandledrejection
|
DedicatedWorkerGlobalScope
interface
Support in all current engines.
[Global=(Worker,DedicatedWorker),Exposed=DedicatedWorker]
interface DedicatedWorkerGlobalScope : WorkerGlobalScope {
[Replaceable] readonly attribute DOMString name;
undefined postMessage(any message, sequence<object> transfer);
undefined postMessage(any message, optional StructuredSerializeOptions options = {});
undefined close();
};
DedicatedWorkerGlobalScope
includes
MessageEventTarget
;
DedicatedWorkerGlobalScope
objects
have
an
associated
inside
port
(a
MessagePort
).
This
port
is
part
of
a
channel
that
is
set
up
when
the
worker
is
created,
but
it
is
not
exposed.
This
object
must
never
be
garbage
collected
before
the
DedicatedWorkerGlobalScope
object.
dedicatedWorkerGlobal
.
name
DedicatedWorkerGlobalScope/name
Support in all current engines.
Returns
dedicatedWorkerGlobal
's
name
,
i.e.
the
value
given
to
the
Worker
constructor.
Primarily
useful
for
debugging.
dedicatedWorkerGlobal
.
postMessage
(
message
[,
transfer
])
DedicatedWorkerGlobalScope/postMessage
Support in all current engines.
dedicatedWorkerGlobal
.
postMessage
(
message
[,
{
transfer
}
])
Clones
message
and
transmits
it
to
the
Worker
object
associated
with
dedicatedWorkerGlobal
.
transfer
can
be
passed
as
a
list
of
objects
that
are
to
be
transferred
rather
than
cloned.
dedicatedWorkerGlobal
.
close
()
DedicatedWorkerGlobalScope/close
Support in all current engines.
Aborts dedicatedWorkerGlobal .
The
name
getter
steps
are
to
return
this
's
name
.
Its
value
represents
the
name
given
to
the
worker
using
the
Worker
constructor,
used
primarily
for
debugging
purposes.
The
postMessage(
message
,
transfer
)
and
postMessage(
message
,
options
)
methods
on
DedicatedWorkerGlobalScope
objects
act
as
if,
when
invoked,
it
immediately
invoked
the
respective
postMessage(
message
,
transfer
)
and
postMessage(
message
,
options
)
on
the
port,
with
the
same
arguments,
and
returned
the
same
return
value.
To close a worker , given a workerGlobal , run these steps:
Discard any tasks that have been added to workerGlobal 's relevant agent 's event loop 's task queues .
Set workerGlobal 's closing flag to true. (This prevents any further tasks from being queued.)
The
close()
method
steps
are
to
close
a
worker
given
this
.
SharedWorkerGlobalScope
interface
Support in all current engines.
[Global=(Worker,SharedWorker),Exposed=SharedWorker]
interface SharedWorkerGlobalScope : WorkerGlobalScope {
[Replaceable] readonly attribute DOMString name;
undefined close();
attribute EventHandler onconnect;
};
A
SharedWorkerGlobalScope
object
has
an
associated
constructor
origin
,
constructor
url
,
and
credentials
.
They
are
initialized
when
the
SharedWorkerGlobalScope
object
is
created,
in
the
run
a
worker
algorithm.
Shared
workers
receive
message
ports
through
connect
events
on
their
SharedWorkerGlobalScope
object
for
each
connection.
sharedWorkerGlobal
.
name
Support in all current engines.
Returns
sharedWorkerGlobal
's
name
,
i.e.
the
value
given
to
the
SharedWorker
constructor.
Multiple
SharedWorker
objects
can
correspond
to
the
same
shared
worker
(and
SharedWorkerGlobalScope
),
by
reusing
the
same
name.
sharedWorkerGlobal
.
close
()
Support in all current engines.
Aborts sharedWorkerGlobal .
The
name
getter
steps
are
to
return
this
's
name
.
Its
value
represents
the
name
that
can
be
used
to
obtain
a
reference
to
the
worker
using
the
SharedWorker
constructor.
The
close()
method
steps
are
to
close
a
worker
given
this
.
The
following
are
the
event
handlers
(and
their
corresponding
event
handler
event
types
)
that
must
be
supported,
as
event
handler
IDL
attributes
,
by
objects
implementing
the
SharedWorkerGlobalScope
interface:
Event handler | Event handler event type |
---|---|
onconnect
SharedWorkerGlobalScope/connect_event Support in all current engines.
Firefox
29+
Safari
16+
Chrome
4+
Opera 10.6+ Edge 79+ Edge (Legacy) ? Internet Explorer No Firefox Android ? Safari iOS 16+ Chrome Android ? WebView Android 37+ Samsung Internet ? Opera Android 11+ |
connect
|
A worker event loop 's task queues only have events, callbacks, and networking activity as tasks . These worker event loops are created by the run a worker algorithm.
Each
WorkerGlobalScope
object
has
a
closing
flag,
which
must
be
initially
false,
but
which
can
get
set
to
true
by
the
algorithms
in
the
processing
model
section
below.
Once
the
WorkerGlobalScope
's
closing
flag
is
set
to
true,
the
event
loop
's
task
queues
must
discard
any
further
tasks
that
would
be
added
to
them
(tasks
already
on
the
queue
are
unaffected
except
where
otherwise
specified).
Effectively,
once
the
closing
flag
is
true,
timers
stop
firing,
notifications
for
all
pending
background
operations
are
dropped,
etc.
Workers
communicate
with
other
workers
and
with
Window
s
through
message
channels
and
their
MessagePort
objects.
Each
WorkerGlobalScope
object
worker
global
scope
has
a
list
of
the
worker's
ports
,
which
consists
of
all
the
MessagePort
objects
that
are
entangled
with
another
port
and
that
have
one
(but
only
one)
port
owned
by
worker
global
scope
.
This
list
includes
the
implicit
MessagePort
in
the
case
of
dedicated
workers
.
Given
an
environment
settings
object
o
when
creating
or
obtaining
a
worker,
the
relevant
owner
to
add
depends
on
the
type
of
global
object
specified
by
o
.
If
o
's
global
object
is
a
WorkerGlobalScope
object
(i.e.,
if
we
are
creating
a
nested
dedicated
worker),
then
the
relevant
owner
is
that
global
object.
Otherwise,
o
's
global
object
is
a
Window
object,
and
the
relevant
owner
is
that
Window
's
associated
Document
.
A
worker
is
said
to
be
a
permissible
worker
if
its
WorkerGlobalScope
's
owner
set
is
not
empty
or:
WorkerGlobalScope
object
is
a
SharedWorkerGlobalScope
object
(i.e.,
the
worker
is
a
shared
worker),
and
The second part of this definition allows a shared worker to survive for a short time while a page is loading, in case that page is going to contact the shared worker again. This can be used by user agents as a way to avoid the cost of restarting a shared worker used by a site when the user is navigating from page to page within that site.
A
worker
is
said
to
be
an
active
needed
worker
if
any
of
its
owners
are
either
Document
objects
that
are
fully
active
or
active
needed
workers
.
A
worker
is
said
to
be
a
protected
worker
if
it
is
an
active
needed
worker
and
either
it
has
outstanding
timers,
database
transactions,
or
network
connections,
or
its
list
of
the
worker's
ports
is
not
empty,
or
its
WorkerGlobalScope
is
actually
a
SharedWorkerGlobalScope
object
(i.e.,
the
worker
is
a
shared
worker).
A worker is said to be a suspendable worker if it is not an active needed worker but it is a permissible worker .
When
a
user
agent
is
to
run
a
worker
for
a
script
with
Worker
or
SharedWorker
object
worker
,
URL
url
,
environment
settings
object
outside
settings
,
MessagePort
outside
port
,
and
a
WorkerOptions
dictionary
options
,
it
must
run
the
following
steps.
Let
is
shared
be
true
if
worker
is
a
SharedWorker
object,
and
false
otherwise.
Let owner be the relevant owner to add given outside settings .
Let unsafeWorkerCreationTime be the unsafe shared current time .
Let agent be the result of obtaining a dedicated/shared worker agent given outside settings and is shared . Run the rest of these steps in that agent.
Let realm execution context be the result of creating a new realm given agent and the following customizations:
For
the
global
object,
if
is
shared
is
true,
create
a
new
SharedWorkerGlobalScope
object.
Otherwise,
create
a
new
DedicatedWorkerGlobalScope
object.
Let worker global scope be the global object of realm execution context 's Realm component.
This
is
the
DedicatedWorkerGlobalScope
or
SharedWorkerGlobalScope
object
created
in
the
previous
step.
Set up a worker environment settings object with realm execution context , outside settings , and unsafeWorkerCreationTime , and let inside settings be the result.
Set
worker
global
scope
's
name
to
the
value
of
options
's
name
member.
If is shared is true, then:
Set worker global scope 's constructor origin to outside settings 's origin .
Set worker global scope 's constructor url to url .
Set
worker
global
scope
's
type
to
the
value
of
options
's
type
member.
Set
worker
global
scope
's
credentials
to
the
value
of
options
's
credentials
member.
Let
destination
be
"
sharedworker
"
if
is
shared
is
true,
and
"
worker
"
otherwise.
Obtain
script
by
switching
on
the
value
of
options
's
type
member:
classic
"
module
"
credentials
member
of
options
,
inside
settings
,
and
with
onComplete
and
performFetch
as
defined
below.
In both cases, let performFetch be the following perform the fetch hook given request , isTopLevel and processCustomFetchResponse :
If isTopLevel is false, fetch request with processResponseConsumeBody set to processCustomFetchResponse , and abort these steps.
Fetch request with processResponseConsumeBody set to the following steps given response response and null, failure, or a byte sequence bodyBytes :
Initialize worker global scope's policy container given worker global scope , response , and inside settings .
If
the
Run
CSP
initialization
for
a
global
object
algorithm
returns
"
Blocked
"
when
executed
upon
worker
global
scope
,
set
response
to
a
network
error
.
[CSP]
If
worker
global
scope
's
embedder
policy
's
value
is
compatible
with
cross-origin
isolation
and
is
shared
is
true,
then
set
agent
's
agent
cluster
's
cross-origin
isolation
mode
to
"
logical
"
or
"
concrete
".
The
one
chosen
is
implementation-defined
.
This really ought to be set when the agent cluster is created, which requires a redesign of this section.
If the result of checking a global object's embedder policy with worker global scope , outside settings , and response is false, then set response to a network error .
Set
worker
global
scope
's
cross-origin
isolated
capability
to
true
if
agent
's
agent
cluster
's
cross-origin
isolation
mode
is
"
concrete
".
If is shared is false and owner 's cross-origin isolated capability is false, then set worker global scope 's cross-origin isolated capability to false.
If
is
shared
is
false
and
response
's
url
's
scheme
is
"
data
",
then
set
worker
global
scope
's
cross-origin
isolated
capability
to
false.
This
is
a
conservative
default
for
now,
while
we
figure
out
how
workers
in
general,
and
data:
URL
workers
in
particular
(which
are
cross-origin
from
their
owner),
will
be
treated
in
the
context
of
permissions
policies.
See
w3c/webappsec-permissions-policy
issue
#207
for
more
details.
Run processCustomFetchResponse with response and bodyBytes .
In both cases, let onComplete given script be the following steps:
If script is null or if script 's error to rethrow is non-null, then:
Queue
a
global
task
on
the
DOM
manipulation
task
source
given
worker
's
relevant
global
object
to
fire
an
event
named
error
at
worker
.
Run the environment discarding steps for inside settings .
Abort these steps.
Associate worker with worker global scope .
Let
inside
port
be
a
new
MessagePort
object
in
inside
settings
's
realm
.
If is shared is false, then:
Set inside port 's message event target to worker global scope .
Set worker global scope 's inside port to inside port .
Entangle outside port and inside port .
Create
a
new
WorkerLocation
object
and
associate
it
with
worker
global
scope
.
Closing orphan workers : Start monitoring the worker such that no sooner than it stops being a protected worker , and no later than it stops being a permissible worker , worker global scope 's closing flag is set to true.
Suspending workers : Start monitoring the worker, such that whenever worker global scope 's closing flag is false and the worker is a suspendable worker , the user agent suspends execution of script in that worker until such time as either the closing flag switches to true or the worker stops being a suspendable worker .
Set inside settings 's execution ready flag .
If script is a classic script , then run the classic script script . Otherwise, it is a module script ; run the module script script .
In addition to the usual possibilities of returning a value or failing due to an exception, this could be prematurely aborted by the terminate a worker algorithm defined below.
Enable outside port 's port message queue .
If is shared is false, enable the port message queue of the worker's implicit port.
If
is
shared
is
true,
then
queue
a
global
task
on
DOM
manipulation
task
source
given
worker
global
scope
to
fire
an
event
named
connect
at
worker
global
scope
,
using
MessageEvent
,
with
the
data
attribute
initialized
to
the
empty
string,
the
ports
attribute
initialized
to
a
new
frozen
array
containing
inside
port
,
and
the
source
attribute
initialized
to
inside
port
.
Enable
the
client
message
queue
of
the
ServiceWorkerContainer
object
whose
associated
service
worker
client
is
worker
global
scope
's
relevant
settings
object
.
Event loop : Run the responsible event loop specified by inside settings until it is destroyed.
The handling of events or the execution of callbacks by tasks run by the event loop might get prematurely aborted by the terminate a worker algorithm defined below.
The worker processing model remains on this step until the event loop is destroyed, which happens after the closing flag is set to true, as described in the event loop processing model.
Clear the worker global scope 's map of active timers .
Disentangle all the ports in the list of the worker's ports .
When a user agent is to terminate a worker it must run the following steps in parallel with the worker's main loop (the " run a worker " processing model defined above):
Set
the
worker's
WorkerGlobalScope
object's
closing
flag
to
true.
If
there
are
any
tasks
queued
in
the
WorkerGlobalScope
object's
relevant
agent
's
event
loop
's
task
queues
,
discard
them
without
processing
them.
Abort the script currently running in the worker.
If
the
worker's
WorkerGlobalScope
object
is
actually
a
DedicatedWorkerGlobalScope
object
(i.e.
the
worker
is
a
dedicated
worker),
then
empty
the
port
message
queue
of
the
port
that
the
worker's
implicit
port
is
entangled
with.
User agents may invoke the terminate a worker algorithm when a worker stops being an active needed worker and the worker continues executing even after its closing flag was set to true.
Whenever
an
uncaught
runtime
script
error
occurs
in
one
of
the
worker's
scripts,
if
the
error
did
not
occur
while
handling
a
previous
script
error,
the
user
agent
will
report
it
for
the
worker's
WorkerGlobalScope
object.
AbstractWorker
mixin
interface mixin AbstractWorker {
attribute EventHandler onerror;
};
The
following
are
the
event
handlers
(and
their
corresponding
event
handler
event
types
)
that
must
be
supported,
as
event
handler
IDL
attributes
,
by
objects
implementing
the
AbstractWorker
interface:
Event handler | Event handler event type |
---|---|
onerror
Support in all current engines.
Firefox
44+
Safari
11.1+
Chrome
40+
Opera ? Edge 79+ Edge (Legacy) 17+ Internet Explorer No Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android ? Support in all current engines.
Firefox
29+
Safari
16+
Chrome
5+
Opera 10.6+ Edge 79+ Edge (Legacy) ? Internet Explorer No Firefox Android 33+ Safari iOS 16+ Chrome Android No WebView Android ? Samsung Internet 4.0–5.0 Opera Android 11–14 Support in all current engines.
Firefox
3.5+
Safari
4+
Chrome
4+
Opera 10.6+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 10+ Firefox Android ? Safari iOS 5+ Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 11+ |
error
|
To set up a worker environment settings object , given a JavaScript execution context execution context , an environment settings object outside settings , and a number unsafeWorkerCreationTime :
Let inherited origin be outside settings 's origin .
Let realm be the value of execution context 's Realm component.
Let worker global scope be realm 's global object .
Let settings object be a new environment settings object whose algorithms are defined as follows:
Return execution context .
Return worker global scope 's module map .
Return worker global scope 's url .
Return
a
unique
opaque
origin
if
worker
global
scope
's
url
's
scheme
is
"
data
",
and
inherited
origin
otherwise.
Return worker global scope 's policy container .
Return worker global scope 's cross-origin isolated capability .
Return the result of coarsening unsafeWorkerCreationTime with worker global scope 's cross-origin isolated capability .
Set
settings
object
's
id
to
a
new
unique
opaque
string,
creation
URL
to
worker
global
scope
's
url
,
top-level
creation
URL
to
null,
target
browsing
context
to
null,
and
active
service
worker
to
null.
null,
and
cross-site
ancestor
flag
to
outside
settings
's
cross-site
ancestor
flag
.
If
worker
global
scope
is
a
DedicatedWorkerGlobalScope
object,
then
set
settings
object
's
top-level
origin
to
outside
settings
's
top-level
origin
.
Otherwise, set settings object 's top-level origin to an implementation-defined value.
See Client-Side Storage Partitioning for the latest on properly defining this.
Set realm 's [[HostDefined]] field to settings object .
Return settings object .
Worker
interface
Support in all current engines.
[Exposed=(Window,DedicatedWorker,SharedWorker)]
interface Worker : EventTarget {
constructor((TrustedScriptURL
or USVString) scriptURL, optional WorkerOptions options = {});
undefined terminate();
undefined postMessage(any message, sequence<object> transfer);
undefined postMessage(any message, optional StructuredSerializeOptions options = {});
};
dictionary WorkerOptions {
WorkerType type = "classic";
RequestCredentials credentials = "same-origin"; // credentials is only used if type is "module"
DOMString name = "";
};
enum WorkerType { "classic", "module" };
Worker includes AbstractWorker;
Worker
includes
MessageEventTarget
;
worker
=
new
Worker
(
scriptURL
[,
options
])
Support in all current engines.
Returns
a
new
Worker
object.
scriptURL
will
be
fetched
and
executed
in
the
background,
creating
a
new
global
environment
for
which
worker
represents
the
communication
channel.
options
can
be
used
to
define
the
name
of
that
global
environment
via
the
name
option,
primarily
for
debugging
purposes.
It
can
also
ensure
this
new
global
environment
supports
JavaScript
modules
(specify
type:
"module"
),
and
if
that
is
specified,
can
also
be
used
to
specify
how
scriptURL
is
fetched
through
the
credentials
option.
worker
.
terminate
()
Support in all current engines.
worker
.
postMessage
(
message
[,
transfer
])
Support in all current engines.
worker
.
postMessage
(
message
[,
{
transfer
}
])
Clones message and transmits it to worker 's global environment. transfer can be passed as a list of objects that are to be transferred rather than cloned.
Each
Worker
object
has
an
associated
outside
port
(a
MessagePort
).
This
port
is
part
of
a
channel
that
is
set
up
when
the
worker
is
created,
but
it
is
not
exposed.
This
object
must
never
be
garbage
collected
before
the
Worker
object.
The
terminate()
method,
when
invoked,
must
cause
the
terminate
a
worker
algorithm
to
be
run
on
the
worker
with
which
the
object
is
associated.
The
postMessage(
message
,
transfer
)
and
postMessage(
message
,
options
)
methods
on
Worker
objects
act
as
if,
when
invoked,
they
immediately
invoked
the
respective
postMessage(
message
,
transfer
)
and
postMessage(
message
,
options
)
on
this
's
outside
port
,
with
the
same
arguments,
and
returned
the
same
return
value.
The
postMessage()
method's
first
argument
can
be
structured
data:
worker.postMessage({opcode:
'activate',
device:
1938,
parameters:
[23,
102]});
When
the
Worker(
scriptURL
,
options
)
constructor
is
invoked,
the
user
agent
must
run
the
following
steps:
Let
compliantScriptURL
be
the
result
of
invoking
the
Get
Trusted
Type
compliant
string
algorithm
with
TrustedScriptURL
,
this
's
relevant
global
object
,
scriptURL
,
"
Worker
constructor
",
and
"
script
".
Let outside settings be the current settings object .
Let worker URL be the result of encoding-parsing a URL given compliantScriptURL , relative to outside settings .
Any
same-origin
URL
(including
blob:
URLs)
can
be
used.
data:
URLs
can
also
be
used,
but
they
create
a
worker
with
an
opaque
origin
.
If
worker
URL
is
failure,
then
throw
a
"
SyntaxError
"
DOMException
.
Let
worker
be
a
new
Worker
object.
Let
outside
port
be
a
new
MessagePort
in
outside
settings
's
realm
.
Set outside port 's message event target to worker .
Set worker 's outside port to outside port .
Run this step in parallel :
Run a worker given worker , worker URL , outside settings , outside port , and options .
Return worker .
SharedWorker
interface
Support in all current engines.
[Exposed=Window]
interface SharedWorker : EventTarget {
constructor((TrustedScriptURL
or USVString) scriptURL, optional (DOMString or WorkerOptions) options = {});
readonly attribute MessagePort port;
};
SharedWorker
includes
AbstractWorker
;
sharedWorker
=
new
SharedWorker
(
scriptURL
[,
name
])
Support in all current engines.
Returns
a
new
SharedWorker
object.
scriptURL
will
be
fetched
and
executed
in
the
background,
creating
a
new
global
environment
for
which
sharedWorker
represents
the
communication
channel.
name
can
be
used
to
define
the
name
of
that
global
environment.
sharedWorker
=
new
SharedWorker
(
scriptURL
[,
options
])
Returns
a
new
SharedWorker
object.
scriptURL
will
be
fetched
and
executed
in
the
background,
creating
a
new
global
environment
for
which
sharedWorker
represents
the
communication
channel.
options
can
be
used
to
define
the
name
of
that
global
environment
via
the
name
option.
It
can
also
ensure
this
new
global
environment
supports
JavaScript
modules
(specify
type:
"module"
),
and
if
that
is
specified,
can
also
be
used
to
specify
how
scriptURL
is
fetched
through
the
credentials
option.
Note
that
attempting
to
construct
a
shared
worker
with
options
whose
type
or
credentials
values
mismatch
an
existing
shared
worker
will
cause
the
returned
sharedWorker
to
fire
an
error
event
and
not
connect
to
the
existing
shared
worker.
sharedWorker
.
port
Support in all current engines.
Returns
sharedWorker
's
MessagePort
object
which
can
be
used
to
communicate
with
the
global
environment.
The
port
attribute
must
return
the
value
it
was
assigned
by
the
object's
constructor.
It
represents
the
MessagePort
for
communicating
with
the
shared
worker.
A user agent has an associated shared worker manager which is the result of starting a new parallel queue .
Each user agent has a single shared worker manager for simplicity. Implementations could use one per origin ; that would not be observably different and enables more concurrency.
When
the
SharedWorker(
scriptURL
,
options
)
constructor
is
invoked:
Let
compliantScriptURL
be
the
result
of
invoking
the
Get
Trusted
Type
compliant
string
algorithm
with
TrustedScriptURL
,
this
's
relevant
global
object
,
scriptURL
,
"
SharedWorker
constructor
",
and
"
script
".
If
options
is
a
DOMString
,
set
options
to
a
new
WorkerOptions
dictionary
whose
name
member
is
set
to
the
value
of
options
and
whose
other
members
are
set
to
their
default
values.
Let outside settings be the current settings object .
Let urlRecord be the result of encoding-parsing a URL given compliantScriptURL , relative to outside settings .
Any
same-origin
URL
(including
blob:
URLs)
can
be
used.
data:
URLs
can
also
be
used,
but
they
create
a
worker
with
an
opaque
origin
.
If
urlRecord
is
failure,
then
throw
a
"
SyntaxError
"
DOMException
.
Let
worker
be
a
new
SharedWorker
object.
Let
outside
port
be
a
new
MessagePort
in
outside
settings
's
realm
.
Assign
outside
port
to
the
port
attribute
of
worker
.
Let callerIsSecureContext be true if outside settings is a secure context ; otherwise, false.
Let outside storage key be the result of running obtain a storage key for non-storage purposes given outside settings .
Enqueue the following steps to the shared worker manager :
Let worker global scope be null.
For
each
scope
in
the
list
of
all
SharedWorkerGlobalScope
objects:
Let worker storage key be the result of running obtain a storage key for non-storage purposes given scope 's relevant settings object .
If all of the following are true:
name
member,
then:
Set worker global scope to scope .
Break .
data:
URLs
create
a
worker
with
an
opaque
origin
.
Both
the
constructor
origin
and
constructor
url
are
compared
so
the
same
data:
URL
can
be
used
within
an
origin
to
get
to
the
same
SharedWorkerGlobalScope
object,
but
cannot
be
used
to
bypass
the
same
origin
restriction.
If worker global scope is not null, but the user agent has been configured to disallow communication between the worker represented by the worker global scope and the scripts whose settings object is outside settings , then set worker global scope to null.
For example, a user agent could have a development mode that isolates a particular top-level traversable from all other pages, and scripts in that development mode could be blocked from connecting to shared workers running in the normal browser mode.
If
worker
global
scope
is
not
null,
then
check
if
worker
global
scope
's
type
and
credentials
match
the
options
values.
If
not,
queue
a
task
to
fire
an
event
named
error
and
abort
these
steps.
If worker global scope is not null, then run these subsubsteps:
Let settings object be the relevant settings object for worker global scope .
Let workerIsSecureContext be true if settings object is a secure context ; otherwise, false.
If
workerIsSecureContext
is
not
callerIsSecureContext
,
then
queue
a
task
to
fire
an
event
named
error
at
worker
and
abort
these
steps.
[SECURE-CONTEXTS]
Associate worker with worker global scope .
Let
inside
port
be
a
new
MessagePort
in
settings
object
's
realm
.
Entangle outside port and inside port .
Queue
a
task
,
using
the
DOM
manipulation
task
source
,
to
fire
an
event
named
connect
at
worker
global
scope
,
using
MessageEvent
,
with
the
data
attribute
initialized
to
the
empty
string,
the
ports
attribute
initialized
to
a
new
frozen
array
containing
only
inside
port
,
and
the
source
attribute
initialized
to
inside
port
.
Append the relevant owner to add given outside settings to worker global scope 's owner set .
Otherwise, in parallel , run a worker given worker , urlRecord , outside settings , outside port , and options .
Return worker .
interface mixin NavigatorConcurrentHardware {
readonly attribute unsigned long long hardwareConcurrency;
};
self
.
navigator
.
hardwareConcurrency
Returns the number of logical processors potentially available to the user agent.
The
navigator.hardwareConcurrency
attribute's
getter
must
return
a
number
between
1
and
the
number
of
logical
processors
potentially
available
to
the
user
agent.
If
this
cannot
be
determined,
the
getter
must
return
1.
User agents should err toward exposing the number of logical processors available, using lower values only in cases where there are user-agent specific limits in place (such as a limitation on the number of workers that can be created) or when the user agent desires to limit fingerprinting possibilities.
The
importScripts(...
urls
)
method
steps
are:
Let urlStrings be « ».
For each url of urls :
Append
the
result
of
invoking
the
Get
Trusted
Type
compliant
string
algorithm
with
TrustedScriptURL
,
this
's
relevant
global
object
,
url
,
"
WorkerGlobalScope
importScripts
",
and
"
script
"
to
urlStrings
.
Import scripts into worker global scope given this and urlStrings .
To
import
scripts
into
worker
global
scope
,
given
a
WorkerGlobalScope
object
worker
global
scope
,
a
list
of
scalar
value
strings
urls
,
and
an
optional
perform
the
fetch
hook
performFetch
:
If
worker
global
scope
's
type
is
"
module
",
throw
a
TypeError
exception.
Let settings object be the current settings object .
If urls is empty, return.
Let urlRecords be « ».
For each url of urls :
Let urlRecord be the result of encoding-parsing a URL given url , relative to settings object .
If
urlRecord
is
failure,
then
throw
a
"
SyntaxError
"
DOMException
.
Append urlRecord to urlRecords .
For each urlRecord of urlRecords :
Fetch a classic worker-imported script given urlRecord and settings object , passing along performFetch if provided. If this succeeds, let script be the result. Otherwise, rethrow the exception.
Run the classic script script , with the rethrow errors argument set to true.
script will run until it either returns, fails to parse, fails to catch an exception, or gets prematurely aborted by the terminate a worker algorithm defined above.
If an exception was thrown or if the script was prematurely aborted , then abort all these steps, letting the exception or aborting continue to be processed by the calling script .
Service Workers is an example of a specification that runs this algorithm with its own perform the fetch hook . [SW]
WorkerNavigator
interface
Support in all current engines.
The
navigator
attribute
of
the
WorkerGlobalScope
interface
must
return
an
instance
of
the
WorkerNavigator
interface,
which
represents
the
identity
and
state
of
the
user
agent
(the
client):
[Exposed=Worker]
interface WorkerNavigator {};
WorkerNavigator includes NavigatorID;
WorkerNavigator includes NavigatorLanguage;
WorkerNavigator includes NavigatorOnLine;
WorkerNavigator
includes
NavigatorConcurrentHardware
;
WorkerLocation
interface
Support in all current engines.
Support in all current engines.
[Exposed=Worker]
interface WorkerLocation {
stringifier readonly attribute USVString href;
readonly attribute USVString origin;
readonly attribute USVString protocol;
readonly attribute USVString host;
readonly attribute USVString hostname;
readonly attribute USVString port;
readonly attribute USVString pathname;
readonly attribute USVString search;
readonly attribute USVString hash;
};
A
WorkerLocation
object
has
an
associated
WorkerGlobalScope
object
(a
WorkerGlobalScope
object).
Support in all current engines.
The
href
getter
steps
are
to
return
this
's
WorkerGlobalScope
object
's
url
,
serialized
.
Support in all current engines.
The
origin
getter
steps
are
to
return
the
serialization
of
this
's
WorkerGlobalScope
object
's
url
's
origin
.
Support in all current engines.
The
protocol
getter
steps
are
to
return
this
's
WorkerGlobalScope
object
's
url
's
scheme
,
followed
by
"
:
".
Support in all current engines.
The
host
getter
steps
are:
Let
url
be
this
's
WorkerGlobalScope
object
's
url
.
If url 's host is null, return the empty string.
If url 's port is null, return url 's host , serialized .
Return
url
's
host
,
serialized
,
followed
by
"
:
"
and
url
's
port
,
serialized
.
Support in all current engines.
The
hostname
getter
steps
are:
Let
host
be
this
's
WorkerGlobalScope
object
's
url
's
host
.
If host is null, return the empty string.
Return host , serialized .
Support in all current engines.
The
port
getter
steps
are:
Let
port
be
this
's
WorkerGlobalScope
object
's
url
's
port
.
If port is null, return the empty string.
Return port , serialized .
Support in all current engines.
The
pathname
getter
steps
are
to
return
the
result
of
URL
path
serializing
this
's
WorkerGlobalScope
object
's
url
.
Support in all current engines.
The
search
getter
steps
are:
Let
query
be
this
's
WorkerGlobalScope
object
's
url
's
query
.
If query is either null or the empty string, return the empty string.
Return
"
?
",
followed
by
query
.
Support in all current engines.
The
hash
getter
steps
are:
Let
fragment
be
this
's
WorkerGlobalScope
object
's
url
's
fragment
.
If fragment is either null or the empty string, return the empty string.
Return
"
#
",
followed
by
fragment
.