1. Introduction
A
service
worker
is
capable
of
fetching
and
caching
assets,
the
size
of
which
is
restricted
only
by
origin
storage
.
However,
if
the
user
navigates
away
from
the
site
or
closes
the
browser,
the
service
worker
is
likely
to
be
killed
.
This
can
happen
even
if
there’s
a
pending
promise
passed
to
waitUntil()
-
if
it
hasn’t
resolved
within
a
few
minutes
the
browser
may
consider
it
an
abuse
of
service
worker
and
kill
the
process.
This is excellent for battery and privacy, but it makes it difficult to download and cache large assets such as podcasts and movies, and upload video and images.
This specification aims to:
-
Allow fetches (requests & responses) to continue even if the user closes all windows & workers to the origin.
-
Allow a single job to involve many requests, as defined by the app.
-
Allow the browser/OS to show UI to indicate the progress of that job, and allow the user to pause/abort.
-
Allow the browser/OS to deal with poor connectivity by pausing/resuming the download.
-
Allow the app to react to success/failure of the job, perhaps by caching the results.
-
Allow access to background-fetched resources as they fetch.
2. Realms
All platform objects are created in this 's relevant Realm unless otherwise specified.
3. Permissions
Background
Fetch
is
a
default
powerful
feature
that
is
identified
by
the
name
"background-fetch".
"
background-fetch
".
4. Infrastructure
A resource is considered temporarily unavailable if the user agent believes the resource may soon become available. Reasons may include:
-
The user agent is offline.
-
The user agent is behind a captive portal.
The background fetch task source is a task source .
4.1. Extensions to service worker registration
A service worker registration additionally has:
-
Active background fetches (a map ), where each key is a DOMString, and each item is a background fetch . It is initially an empty map .
-
An active background fetches edit queue (a parallel queue ), initially the result of starting a new parallel queue .
4.2. Background fetch
A background fetch consists of:
-
An id (a DOMString).
-
Records (a list of background fetch records ).
-
A title (a DOMString).
-
A download total (a number).
-
An upload total (a number).
-
A uploaded (a number), initially 0.
-
A result (a
BackgroundFetchResult), initially the empty string. -
A failure reason (a
BackgroundFetchFailureReason), initially the empty string. -
A records available flag initially set.
-
Icons (a list of
ImageResources). -
A service worker registration (a service worker registration ).
-
A update handling queue (a parallel queue ), initially the result of starting a new parallel queue .
-
A paused flag , initially unset.
-
A abort all flag , initially unset.
-
Let total be 0.
-
For each record of bgFetch ’s records :
-
Increment total by the length of record ’s response data 's bytes .
-
-
Return total .
4.2.1. Display
-
The UI must prominently display the bgFetch ’s service worker registration 's scope url 's origin
-
If the bgFetch ’s paused flag is unset, and bgFetch ’s result is not the empty string, then the UI must indicate that bandwidth is being used.
-
The UI cannot be dismissed without aborting (e.g. swiped away) until bgFetch ’s result is not the empty string.
-
The UI may display bgFetch ’s title .
-
The UI may select an image resource ( icon ) for display from bgFetch ’s icons , after successfully processing it, and fetch it using a new request with the following properties:
- URL
-
icon ’s src .
- Client
-
environment .
- Keepalive
-
True.
- Service-workers mode
-
"
none". - Destination
-
"
image". - Mode
-
"
no-cors". - Credentials mode
-
"
include".
-
The UI may use bgFetch ’s download total , upload total , stored body bytes total , uploaded , paused flag , and result to present the progress of the fetch.
-
The UI must provide a way for the user to abort the bgFetch by setting bgFetch ’s abort all flag .
-
If every request in bgFetch ’s records has the method `
GET`, the UI may provide a way to toggle bgFetch ’s paused flag .Note: If a method is not `
GET`, reissuing the request may have unwanted side effects. -
The UI may be activated (for example, by clicking), in which case fire a background fetch click event for bgFetch .
-
The UI may remain once the operation is complete, in which case it can still be activated.
Let
permission
be
the
permission
state
for
a
PermissionDescriptor
with
name
"background-fetch"
and
environment
.
If
permission
is
"prompt"
,
then
the
user
agent
may
set
bgFetch
’s
paused
flag
at
the
beginning
of
this
algorithm.
The
user
agent
should
allow
the
user
to
either
accept
the
background
fetch
(unsetting
bgFetch
’s
paused
flag
),
or
refuse
the
background
fetch
(setting
bgFetch
’s
abort
all
flag
).
The
user
agent
may
also
provide
always-allow
and
alway-deny
options,
which
can
be
used
as
new
information
about
the
user’s
intent
for
this
permission.
The user agent may also consider setting bgFetch ’s paused flag if the user is on a metered connection, or the background fetch was started in the background.
4.3. Background fetch record
A background fetch record consists of:
-
A request (a request ).
-
A response data (a background fetch response ), initially a new background fetch response .
4.4. Background fetch response
A Background fetch response consists of:
-
A response (a response or null), initially null.
-
Bytes (a byte sequence ), initially an empty byte sequence .
-
A result , (any
BackgroundFetchFailureReason,"success", or"redundant"), initially the empty string.
The
response
can
be
exposed
if
the
result
is
the
empty
string,
"success"
,
or
"bad-status"
.
5. Algorithms
5.1. Perform a background fetch
Note: This is the algorithm that manages the 'background' parts of a background fetch. Only one instance of this algorithm runs per background fetch .
-
Let swRegistration be bgFetch ’s service worker registration .
-
Let settledFetches be 0.
-
Let immediateFailure be false.
-
Let failureReason be the empty string.
-
For each record in bgFetch ’s records , run these steps in parallel :
-
Complete a record for bgFetch and record .
-
Let result be record ’s response data 's result .
-
If failureReason is not the empty string:
-
Assert: result is not
"redundant". -
Set failureReason to result .
-
-
Increment settledFetches by 1.
-
If result is
"download-total-exceeded", then set immediateFailure to true.
-
-
Wait for settledFetches to be bgFetch ’s records 's size , or immediateFailure to be true.
-
If immediateFailure is true, set bgFetch ’s abort all flag .
Note: The complete a record algorithm listens to this flag and terminates the fetch when set.
-
Enqueue the following steps to swRegistration ’s active background fetches edit queue :
-
Let activeBgFetches be swRegistration ’s active background fetches .
-
Let id be bgFetch ’s id .
-
If activeBgFetches contains background fetch bgFetch , then remove activeBgFetches [ id ].
-
Otherwise, set failureReason to
"aborted".Note: This handles a race condition where
abort()was successfully called but one of the fetches failed at the same time. If we’ve returned true fromabort(), this ensures we fire the related abort event. -
If failureReason is not the empty string, then:
-
Set bgFetch ’s result to
"failure". -
Set bgFetch ’s failure reason to failureReason .
-
-
Otherwise, set bgFetch ’s result to
"success". -
Update background fetch instances for bgFetch .
-
Let eventName be the empty string.
-
Let eventConstructor be null.
-
If failureReason is
"aborted", then:-
Set eventName to "
backgroundfetchabort". -
Set eventConstructor to
BackgroundFetchEvent.
-
-
Otherwise, if failureReason is not the empty string, then:
-
Set eventName to "
backgroundfetchfail". -
Set eventConstructor to
BackgroundFetchUpdateUIEvent.
-
-
Otherwise:
-
Set eventName to "
backgroundfetchsuccess". -
Set eventConstructor to
BackgroundFetchUpdateUIEvent.
-
-
Fire a functional event named eventName using eventConstructor on swRegistration with the following properties:
-
registration -
The result of getting a BackgroundFetchRegistration instance for bgFetch in the event object’s relevant Realm .
Then run these steps with dispatchedEvent in parallel :
-
Wait until dispatchedEvent is not active .
-
Unset bgFetch ’s records available flag .
-
Update background fetch instances for bgFetch .
-
-
5.2. Complete a record
Note: This algorithm manages the fetching of a background fetch record . One instance of this algorithm is started per background fetch record , but it is called recursively to retry fetches or to fetch the next part of a partial response.
-
Let responseData be record ’s response data .
-
Let downloadTotal be bgFetch ’s download total if it is not 0, otherwise infinity.
-
Wait for bgFetch ’s paused flag to be unset.
-
Let request be a copy of record ’s request .
Note: At this point the request is entirely held in storage, even if it started as a stream.
-
Set request ’s keepalive to true.
-
Set request ’s service-workers mode to "
none". -
If rangeStart is not 0, then add a range header to request with rangeStart .
Note: If the rangeStart is 0, a normal request is made. This allows the initial request to make use of content encoding, since
Accept-Encoding: identityis added to requests with a range header. -
Let fetchAttemptComplete be false.
-
Let lastTransmittedSize be 0.
-
Fetch request .
The remainder of this step uses fetch "callbacks" which currently queue tasks. This isn’t desirable or possible here, so let’s pretend that tasks aren’t queued. ( issue )
To process request body for request , run these steps:
-
Let transmittedSize be request ’s body 's transmitted bytes .
-
Increment bgFetch ’s uploaded by transmittedSize minus lastTransmittedSize .
-
Set lastTransmittedSize to transmittedSize .
-
Update background fetch instances for bgFetch .
To process response for response , run these steps:
-
If response is a network error , then:
-
If the resource is temporarily unavailable and request ’s method is `
GET`, then wait until the resource is not temporarily unavailable , then set fetchAttemptComplete to true and abort these steps.Note: If request ’s method is not `
GET`, reissuing the request may have unwanted side effects. If a standard method to resume requests becomes available, it’ll be adopted here. -
If response is an aborted network error , then set responseData ’s result to
"aborted", otherwise"fetch-error". -
Set fetchAttemptComplete to true, and abort these steps.
-
-
If response ’s status is
206, then:-
If validate a partial response for rangeStart , response , and responseData ’s response returns invalid, then:
-
-
Otherwise:
-
Set responseData ’s result to
"redundant". -
Set responseData to a new background fetch response .
-
Set record ’s response data to responseData .
Note: The create record objects algorithm may hold a reference to the previous background fetch response .
-
Update background fetch instances for bgFetch .
-
-
If rangeStart is 0 or response ’s status is not
206, then set responseData ’s response to a copy of response except for its body . -
Whenever one or more bytes are transmitted from stream , let bytes be the transmitted bytes and run these steps:
-
If bgFetch ’s stored body bytes total plus the size of bytes is greater than downloadTotal , then:
-
Append bytes to responseData ’s bytes .
-
If the previous step fails due to exceeding a quota limit, set responseData ’s result to
"quota-exceeded", fetchAttemptComplete to true, and abort these steps. -
Update background fetch instances for bgFetch .
-
-
If at any point the bytes transmission for stream is done normally, then:
-
If response ’s status is
206, then:-
Let firstBytePos , lastBytePos , and completeLength be the result of extracting content-range values from response .
-
If completeLength is not null, and equal to the length of responseData ’s bytes , set responseData ’s result to
"success".Note: Although we ask for the whole resource, or the remainder of the resource, the server may not have returned the remainder, in which case we need to make an additional request.
-
-
Otherwise, if response ’s status is not an ok status , set responseData ’s result to
"bad-status". -
Otherwise, set responseData ’s result to
"success". -
Set fetchAttemptComplete to true.
-
-
If at any point stream becomes errored , then:
-
If the resource is temporarily unavailable and request ’s method is `
GET`, then wait until the resource is not temporarily unavailable , then set fetchAttemptComplete to true. -
Otherwise, set responseData ’s result to
"fetch-error"and fetchAttemptComplete to true.
-
-
-
Let result be the empty string.
-
Run these steps, but abort when bgFetch ’s paused flag or abort all flag is set:
-
Wait for fetchAttemptComplete to be true.
-
Set result to responseData ’s result .
-
-
If aborted , then:
-
If bgFetch ’s paused flag is set, then assert request ’s method is `
GET`. -
If bgFetch ’s abort all flag is set, then set responseData ’s result to
"aborted". -
Set result to responseData ’s result .
Note: The result is stored now, as terminating the fetch may change the result.
-
Terminate the ongoing fetch.
-
-
If result is the empty string, then complete a record for bgFetch and record .
5.3. Update background fetch instances
-
Let downloaded be bgFetch ’s stored body bytes total .
-
Let uploaded be bgFetch ’s uploaded .
-
Let result be bgFetch ’s result .
-
Let failureReason be bgFetch ’s failure reason .
-
Let recordsAvailable be true if bgFetch ’s records available flag is set, otherwise false.
-
For each environment settings object env whose origin is equal to bgFetch ’s service worker registration 's scope URL 's origin , queue a bgfetch task on env ’s responsible event loop to run these steps:
-
Let bgFetchRegistration be the instance of
BackgroundFetchRegistrationwithin the relevant realm whose background fetch is equal to bgFetch , or null if none exists.Note: There will be at most one per environment, due to the get a BackgroundFetchRegistration instance algorithm.
-
If bgFetchRegistration is null, then abort these steps.
-
If recordsAvailable is false and bgFetchRegistration ’s records available flag is set, then unset bgFetchRegistration ’s records available flag .
-
If bgFetchRegistration ’s result is not the empty string, then abort these steps.
Note: This prevents progress being reported after the background fetch has settled. This is possible when the operation has aborted, but some fetches haven’t yet terminated.
-
If all of the following are true:
-
bgFetchRegistration ’s downloaded is equal to downloaded .
-
bgFetchRegistration ’s uploaded is equal to uploaded .
-
bgFetchRegistration ’s result is equal to result .
-
bgFetchRegistration ’s failure reason is equal to failureReason .
Then abort these steps.
-
-
Set bgFetchRegistration ’s downloaded to downloaded .
-
Set bgFetchRegistration ’s uploaded to uploaded .
-
Set bgFetchRegistration ’s result to result .
-
Set bgFetchRegistration ’s failure reason to failureReason .
-
Fire an event named "
progress" at bgFetchRegistration .
I need to debounce this similar to how mouse move events debounce.
-
5.4. Fire a background fetch click event
backgroundfetchclick
"
using
BackgroundFetchEvent
on
bgFetch
’s
service
worker
registration
with
the
following
properties:
-
registration -
The result of getting a BackgroundFetchRegistration instance for bgFetch in the event object’s relevant Realm .
5.5. Get a BackgroundFetchRegistration instance
Note:
This
algorithm
ensures
the
same
BackgroundFetchRegistration
instance
is
returned
for
a
given
background
fetch
throughout
the
life
of
a
BackgroundFetchManager
.
It’s
okay
for
browsers
to
optimise
this,
as
long
as
there’s
no
way
to
tell
that
more
than
one
instance
has
been
created
for
a
given
background
fetch
(e.g.
through
equality,
expandos,
or
weakly-associated
data).
-
Let instancesMap be the BackgroundFetchRegistration instances of the only instance of
BackgroundFetchManagerwithin this realm . -
If instancesMap [ bgFetch ] exists , then return instancesMap [ bgFetch ].
-
Let instance be a new
BackgroundFetchRegistrationin realm , with its background fetch set to bgFetch . -
Set instancesMap [ bgFetch ] to instance .
-
Return instance .
5.6. Validate a partial response
Note: This algorithm checks if a partial response reasonably matches what was requested, and optionally checks if it should be combined with a previous response.
-
Assert: partialResponse ’s status is
206. -
Let responseFirstBytePos , responseLastBytePos , and responseCompleteLength be the result of extracting content-range values from partialResponse . If this fails, then return invalid.
-
If responseFirstBytePos does not equal expectedRangeStart , then return invalid.
-
If previousResponse is not null, then:
-
For headerName of « `
ETag`, `Last-Modified` »:-
If previousResponse ’s header list contains headerName and the combined value of headerName in previousResponse ’s header list does not equal the combined value of headerName in partialResponse ’s header list , then return invalid.
-
-
If previousResponse ’s status is
206, then:-
Let previousResponseFirstBytePos , previousResponseLastBytePos , and previousResponseCompleteLength be the result of extracting content-range values from previousResponse . If this fails, then return invalid.
-
If previousResponseCompleteLength is not null, and responseCompleteLength does not equal previousResponseCompleteLength , then return invalid.
-
-
-
Return valid.
5.7. Extract content-range values
Note:
This
algorithm
parses
`
Content-Range
`
as
a
single
byte
content-range
and
extracts
the
values.
-
If response ’s header list does not contain `
Content-Range`, then return failure. -
Let contentRangeValue be the value of the first header whose name is a byte-case-insensitive match for `
Content-Range` in response ’s header list . -
If parsing contentRangeValue per single byte content-range fails, then return failure.
-
Let firstBytePos be the portion of contentRangeValue named
first-byte-poswhen parsed as single byte content-range , parsed as an integer. -
Let lastBytePos be the portion of contentRangeValue named
last-byte-poswhen parsed as single byte content-range , parsed as an integer. -
Let completeLength be the portion of contentRangeValue named
complete-lengthwhen parsed as single byte content-range . -
If completeLength is
"*", then set completeLength to null, otherwise set completeLength to completeLength parsed as an integer. -
Return firstBytePos , lastBytePos , and completeLength .
Parsing as an integer infra/189 .
5.8. Create record objects
Note: This algorithm creates platform objects for background fetch records . It also manages the streaming of the response from the stored bytes . The background fetch operation may still be in progress at this point.
All platform objects must be created in realm .
-
Let recordObjects be a new list .
-
For each record of records :
-
Let responseData be record ’s response data .
-
Let recordObject be a new
BackgroundFetchRecord. -
Set recordObject ’s
responseReadyto a new promise . -
Let requestObject be a new
Requestobject with the following set: -
Set recordObject ’s
requestto requestObject . -
Let transmittedBytes be 0.
-
Let stream be a new
ReadableStream. -
Set up stream given a pull action that returns a new promise promise and runs these steps in parallel :
-
Wait for the length of responseData ’s bytes to be greater than transmittedBytes , or responseData ’s result not to be the empty string.
-
Let bytes be null.
-
If the length of responseData ’s bytes is greater than transmittedBytes and responseData may be exposed , then:
-
Queue a task in stream ’s relevant settings object 's responsible event loop using the networking task source to run these steps:
-
If bytes is not null, then:
-
Let array be a new
Uint8Arraywrapping a newArrayBufferof bytes . -
Enqueue array into stream .
-
-
If responseData may be exposed , responseData ’s result is not the empty string, and transmittedBytes is the length of responseData ’s bytes , then close stream .
-
Otherwise, if responseData ’s result is
"aborted", then error stream with anAbortErrorDOMException. -
Otherwise, if responseData may not be exposed , then error stream with a
TypeError. -
Resolve promise .
-
-
-
Run these steps in parallel :
-
Wait for responseData ’s response to not be not-null.
-
If responseData may be exposed , then:
-
Let response be a copy of responseData ’s response .
-
Delete `
Content-Range` from response ’s header list . -
Delete `
Content-Length` from response ’s header list . -
Set response ’s body to body .
-
Queue a task in recordObject ’s relevant settings object 's responsible event loop using the networking task source to run these steps:
-
Let responseObject be a new
Responseobject with the following set: -
Resolve recordObject ’s
responseReadywith responseObject .
-
-
-
Otherwise, if responseData ’s result is
"aborted", then reject recordObject ’sresponseReadywith anAbortErrorDOMException. -
Otherwise, reject recordObject ’s
responseReadywith aTypeError.
-
-
Append recordObject to recordObjects .
-
-
Return recordObjects .
5.9. Contains background fetch
-
If map contains background fetch bgFetch , then return false.
-
Return true.
6. Header syntax
The following is HTTP ABNF for a single byte content-range :
"bytes=" first-byte-pos "-" last-byte-pos "/" complete-length first-byte-pos = 1*DIGIT last-byte-pos = 1*DIGIT complete-length = ( 1*DIGIT / "*" )
Note: This is a subset of what RFC 7233 allows.
The above as a railroad diagram:
7. API
7.1.
Extensions
to
ServiceWorkerGlobalScope
partial interface ServiceWorkerGlobalScope {attribute EventHandler ;onbackgroundfetchsuccess attribute EventHandler ;onbackgroundfetchfail attribute EventHandler ;onbackgroundfetchabort attribute EventHandler ; };onbackgroundfetchclick
7.1.1. Events
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 type | event handler | Interface |
|---|---|---|
backgroundfetchsuccess
|
onbackgroundfetchsuccess
|
BackgroundFetchUpdateUIEvent
|
backgroundfetchfail
|
onbackgroundfetchfail
|
BackgroundFetchUpdateUIEvent
|
backgroundfetchabort
|
onbackgroundfetchabort
|
BackgroundFetchEvent
|
backgroundfetchclick
|
onbackgroundfetchclick
|
BackgroundFetchEvent
|
7.2.
Extensions
to
ServiceWorkerRegistration
partial interface ServiceWorkerRegistration {readonly attribute BackgroundFetchManager backgroundFetch ; };
A
ServiceWorkerRegistration
has
a
background
fetch
manager
(a
BackgroundFetchManager
),
initially
a
new
BackgroundFetchManager
whose
service
worker
registration
is
this
's
service
worker
registration
.
The
backgroundFetch
attribute’s
getter
must
return
this
's
background
fetch
manager
.
7.3.
BackgroundFetchManager
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
[Exposed =(Window ,Worker )]interface {BackgroundFetchManager Promise <BackgroundFetchRegistration >fetch (DOMString , (id RequestInfo or sequence <RequestInfo >),requests optional BackgroundFetchOptions = {});options Promise <BackgroundFetchRegistration ?>get (DOMString );id Promise <sequence <DOMString >>getIds (); };dictionary {BackgroundFetchUIOptions sequence <ImageResource >;icons DOMString ; };title dictionary :BackgroundFetchOptions BackgroundFetchUIOptions {unsigned long long = 0; };downloadTotal
A
BackgroundFetchManager
has:
-
BackgroundFetchRegistration instances (a map ), where the keys are background fetches and the values are
BackgroundFetchRegistrationobjects. It is initially an empty map . -
A service worker registration (a service worker registration ).
7.3.1.
fetch()
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
fetch(
id
,
requests
,
options
)
method,
when
invoked,
run
these
steps:
-
Let registration be this 's service worker registration .
-
Let records be a new list .
-
Let uploadTotal be 0.
-
If requests is a
RequestInfo, set requests to « requests ». -
If requests is empty , then return a promise rejected with a
TypeError. -
For each request of requests :
-
Let internalRequest be the request of the result of invoking the
Requestconstructor with request . If this throws an exception, return a promise rejected with the exception. -
If internalRequest ’s mode is "
no-cors", then return a promise rejected with aTypeError. -
Set internalRequest ’s client to null.
-
Let record be a new background fetch record .
-
Set record ’s request to internalRequest .
-
Append record to records .
-
-
Let promise be a new promise .
-
Enqueue the following steps to registration ’s active background fetches edit queue :
-
Let permission be the permission state for a
PermissionDescriptorwithname"background-fetch", and this 's relevant settings object . -
If permission is
"denied", then reject promise with aNotAllowedErrorDOMExceptionand abort these steps. -
Let bgFetchMap be registration ’s active background fetches .
-
If registration ’s active worker is null, then reject promise with a
TypeErrorand abort these steps. -
If bgFetchMap [ id ] exists , reject promise with a
TypeErrorand abort these steps. -
Let requestBodiesRemaining be the size of requests .
-
Let requestReadFailed be false.
-
For each request of requests :
-
Run these steps in parallel :
-
Run these steps but abort when requestReadFailed is true:
Note: This ensures we have a copy of the request bytes before resolving.
-
If aborted and stream is readable , then error stream with an
AbortErrorDOMExceptionand abort these steps. -
Decrement requestBodiesRemaining by 1.
-
-
If at any point storing requests fails due to exceeding a quota limit, reject promise with a
QuotaExceededErrorDOMExceptionand abort these steps. -
Wait for requestBodiesRemaining to be 0, or requestReadFailed to be true.
-
If requestReadFailed is true, then reject promise with a
TypeErrorand abort these steps. -
Let bgFetch be a new background fetch with:
- id
-
id .
- records
-
records .
- download total
-
options ’
downloadTotalmember. - upload total
-
uploadTotal .
- icons
-
options ’
iconsmember if present, otherwise an empty list . - title
-
options ’
titlemember if present, otherwise the empty string. - service worker registration
-
registration .
-
Set bgFetchMap [ id ] to bgFetch .
-
Queue a bgfetch task to run these steps:
-
Resolve promise with the result of getting a BackgroundFetchRegistration instance for bgFetch in this 's relevant Realm .
-
-
In parallel , display bgFetch from this 's relevant settings object .
-
In parallel , perform a background fetch with bgFetch .
-
-
Return promise .
7.3.2.
get()
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
get(
id
)
method,
when
invoked,
must
return
a
new
promise
promise
and
run
these
steps
in
parallel
:
-
Let registration be this 's associated service worker registration .
-
Let bgFetch be registration ’s active background fetches [ id ].
-
If bgFetch is undefined, then resolve promise with undefined and abort these steps.
-
Enqueue the following steps to bgFetch ’s update handling queue :
-
Queue a bgfetch task task to run these steps:
-
Let bgFetchRegistration be the result of getting a BackgroundFetchRegistration instance for bgFetch in this 's relevant Realm .
-
Resolve promise with bgFetchRegistration .
-
-
Wait for task to complete.
Note: This ensures the potential new instance of
BackgroundFetchRegistrationdoesn’t miss anyprogressevents.
-
7.3.3.
getIds()
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
getIds()
method,
when
invoked,
must
return
a
new
promise
promise
and
run
these
steps
in
parallel
:
-
Let registration be this 's associated service worker registration .
-
Resolve promise with the result of getting the keys of registration ’s active background fetches .
7.4.
BackgroundFetchRegistration
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
[Exposed =(Window ,Worker )]interface :BackgroundFetchRegistration EventTarget {readonly attribute DOMString id ;readonly attribute unsigned long long uploadTotal ;readonly attribute unsigned long long uploaded ;readonly attribute unsigned long long downloadTotal ;readonly attribute unsigned long long downloaded ;readonly attribute BackgroundFetchResult result ;readonly attribute BackgroundFetchFailureReason failureReason ;readonly attribute boolean recordsAvailable ;attribute EventHandler onprogress ;Promise <boolean >abort ();Promise <BackgroundFetchRecord >match (RequestInfo ,request optional CacheQueryOptions = {});options Promise <sequence <BackgroundFetchRecord >>matchAll (optional RequestInfo ,request optional CacheQueryOptions = {}); };options enum {BackgroundFetchResult ,"" ,"success" };"failure" enum { // The background fetch has not completed yet, or was successful.BackgroundFetchFailureReason , // The operation was aborted by the user, or abort() was called."" , // A response had a not-ok-status."aborted" , // A fetch failed for other reasons, e.g. CORS, MIX, an invalid partial response, // or a general network failure for a fetch that cannot be retried."bad-status" , // Storage quota was reached during the operation."fetch-error" , // The provided downloadTotal was exceeded."quota-exceeded" };"download-total-exceeded"
A
BackgroundFetchRegistration
instance
has:
-
A background fetch (a background fetch ).
-
A downloaded (a number), initially a copy of background fetch 's stored body bytes total .
-
A uploaded (a number), initially a copy of background fetch 's uploaded .
-
A result (a
BackgroundFetchResult), initially a copy of background fetch 's result . -
A failure reason (a
BackgroundFetchFailureReason), initially a copy of background fetch 's failure reason . -
An id (a number), a copy of background fetch 's id .
-
An upload total (a number), a copy of background fetch 's upload total .
-
A download total (a number), a copy of background fetch 's download total .
-
A records available flag initially set if background fetch 's records available flag is set, otherwise unset.
Note: The above values are copied so they’re available synchronously.
BackgroundFetchRegistration/id
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
The
id
attribute’s
getter
must
return
this
's
id
.
BackgroundFetchRegistration/uploadTotal
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
The
uploadTotal
attribute’s
getter
must
return
this
's
upload
total
.
BackgroundFetchRegistration/downloadTotal
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
The
downloadTotal
attribute’s
getter
must
return
this
's
download
total
.
BackgroundFetchRegistration/uploaded
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
The
uploaded
attribute’s
getter
must
return
this
's
uploaded
.
BackgroundFetchRegistration/downloaded
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
The
downloaded
attribute’s
getter
must
return
this
's
downloaded
.
BackgroundFetchRegistration/result
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
The
result
attribute’s
getter
must
return
this
's
result
.
BackgroundFetchRegistration/failureReason
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
The
failureReason
attribute’s
getter
must
return
this
's
failure
reason
.
BackgroundFetchRegistration/recordsAvailable
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
The
recordsAvailable
attribute’s
getter
must
return
true
if
this
's
records
available
flag
is
set,
otherwise
false.
7.4.1. Events
BackgroundFetchRegistration/progress_event
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
The
onprogress
event
handler
has
the
event
handler
event
type
of
progress
.
The
progress
event
uses
the
Event
interface.
7.4.2.
abort()
BackgroundFetchRegistration/abort
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
abort()
method,
when
invoked,
must
return
a
new
promise
promise
and
run
these
steps
in
parallel
:
-
Let bgFetch be this 's associated background fetch .
-
Let swRegistration be bgFetch ’s service worker registration .
-
Enqueue the following steps to swRegistration ’s active background fetches edit queue :
-
Let activeBgFetches be swRegistration ’s active background fetches .
-
Let id be bgFetch ’s id .
-
If activeBgFetches does not contain background fetch bgFetch , then resolve promise with false and abort these steps.
-
Remove activeBgFetches [ id ].
-
Resolve promise with true.
-
Set bgFetch ’s abort all flag .
-
7.4.3.
match()
BackgroundFetchRegistration/match
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
match(
request
,
options
)
method,
when
invoked,
must
run
these
steps:
-
Let promise be the result of calling the algorithm
matchAll()passing request and options . -
Return the result of reacting to promise with a fulfilment handler that, when called with argument matches , returns matches [0].
Note:
User
agents
are
encouraged
to
optimise
the
above
so
it’s
faster
than
calling
matchAll()
.
7.4.4.
matchAll()
BackgroundFetchRegistration/matchAll
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
matchAll(
request
,
options
)
method,
when
invoked,
must
run
these
steps:
-
If this 's records available flag is unset, return a promise rejected with an
InvalidStateErrorDOMException. -
Let promise be a new promise .
-
Run these steps in parallel :
-
Let matchingRecords be an empty list .
-
For each record of this 's background fetch 's records :
-
If request matches cached item for request , record ’s request , record ’s response data 's response , and options returns true, then append record to matchingRecords .
-
-
Queue a bgfetch task to resolve promise with the result of creating record objects from matchingRecords in this 's relevant Realm .
-
-
Return promise .
7.5.
BackgroundFetchRecord
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
[Exposed =(Window ,Worker )]interface {BackgroundFetchRecord readonly attribute Request request ;readonly attribute Promise <Response >responseReady ; };
BackgroundFetchRecord
has:
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
The
request
attribute’s
getter
must
return
this
's
request
.
BackgroundFetchRecord/responseReady
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
The
responseReady
attribute’s
getter
must
return
this
's
response
promise
.
7.6.
BackgroundFetchEvent
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
BackgroundFetchEvent/BackgroundFetchEvent
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
[Exposed =ServiceWorker ]interface :BackgroundFetchEvent ExtendableEvent {(constructor DOMString ,type BackgroundFetchEventInit );init readonly attribute BackgroundFetchRegistration registration ; };dictionary :BackgroundFetchEventInit ExtendableEventInit {required BackgroundFetchRegistration ; };registration
BackgroundFetchEvent
has
a
background
fetch
(a
background
fetch
),
initially
the
background
fetch
of
the
value
registration
was
initialized
to.
BackgroundFetchEvent/registration
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
The
registration
attribute
must
return
the
value
it
was
initialized
to.
7.7.
BackgroundFetchUpdateUIEvent
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
BackgroundFetchUpdateUIEvent/BackgroundFetchUpdateUIEvent
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
[Exposed =ServiceWorker ]interface :BackgroundFetchUpdateUIEvent BackgroundFetchEvent {(constructor DOMString ,type BackgroundFetchEventInit );init Promise <undefined >updateUI (optional BackgroundFetchUIOptions = {}); };options
A
BackgroundFetchUpdateUIEvent
has
an
UI
updated
flag
which
is
initially
unset.
7.7.1.
updateUI()
BackgroundFetchUpdateUIEvent/updateUI
In only one current engine.
Opera ? Edge 79+
Edge (Legacy) ? IE None
Firefox for Android ? iOS Safari ? Chrome for Android ? Android WebView None Samsung Internet ? Opera Mobile ?
updateUI(
options
)
method,
when
invoked,
must
return
a
new
promise
promise
and
run
these
steps
in
parallel
:
-
If any of the following is true:
-
this 's UI updated flag is set.
Throw an
InvalidStateErrorDOMException. -
Set this 's UI updated flag .
-
If options is null, return.
-
Let bgFetch be this 's background fetch .
-
If options ’s
iconsmember is present, set bgFetch ’s icons to options ’sicons. -
If options ’s
titlemember is present, set bgFetch ’s title to options ’stitle. -
Resolve promise .
8. Automation
For the purposes of user-agent automation and application testing, this document defines the following extension command for the [WebDriver] specification.
8.1. Click
| Method | URI Template |
|---|---|
| POST | /session/{session id}/backgroundfetch/{ id }/click |
The background fetch click extension command simulates the user activating the display of a background fetch . The remote end steps are:
-
If the current top-level browsing context is no longer open , then return a WebDriver error with WebDriver error code no such window .
-
Let pageURL be the current top-level browsing context 's active document 's URL .
-
Let swRegistration be the matching service worker registration for pageURL .
-
If swRegistration is null, then return a WebDriver error with status
400and JSON error code "invalid service worker state". -
Let bgFetch be the newest background fetch with an id of url variable id and a service worker registration of swRegistration , or null if none exists.
-
If bgFetch is null, then return a WebDriver error with status
404and JSON error code "background fetch not found". -
Fire a background fetch click event for bgFetch .
-
Return WebDriver success .
9. Privacy and bandwidth usage
Fetches can be large and take a long time to complete. During this time the user will be fetching data from one or more servers. The user’s IP address, which may change during the operation, could be used to track the user’s location over time.
To mitigate this, the steps for displaying a background fetch require:
-
Displaying the origin of the site making the fetch.
-
The UI cannot be dismissed while the background fetch is active.
-
Allowing the operation to be easily aborted.
-
Allowing the operation to start in a paused state, requiring user interaction to begin.
The steps also allow a user agent to pause the background fetch if the user is on a metered connection.
All data stored is associated with a particular service worker registration . Clearing a service worker registration will clear all associated background fetches .