Goals
To unify fetching across the web platform this specification supplants a number of algorithms and specifications:
- HTML Standard’s fetch and potentially CORS-enabled fetch algorithms [HTML]
- CORS [CORS]
-
HTTP
`
Origin
` header semantics [ORIGIN]
Unifying fetching provides consistent handling of:
- URL schemes
- Redirects
- Cross-origin semantics
- CSP [CSP]
- Service workers [SW]
- Mixed Content [MIX]
-
`
Referer
` [REFERRER]
1. Preface
At a high level, fetching a resource is a fairly simple operation. A request goes in, a response comes out. The details of that operation are however quite involved and used to not be written down carefully and differ from one API to the next.
Numerous
APIs
provide
the
ability
to
fetch
a
resource,
e.g.
HTML’s
img
and
script
element,
CSS'
cursor
and
list-style-image
,
the
navigator.sendBeacon()
and
self.importScripts()
JavaScript
APIs.
The
Fetch
Standard
provides
a
unified
architecture
for
these
features
so
they
are
all
consistent
when
it
comes
to
various
aspects
of
fetching,
such
as
redirects
and
the
CORS
protocol.
The
Fetch
Standard
also
defines
the
fetch()
JavaScript
API,
which
exposes
most
of
the
networking
functionality
at
a
fairly
low
level
of
abstraction.
2. Infrastructure
This specification depends on the Infra Standard. [INFRA]
This specification uses terminology from the ABNF, Encoding, HTML, HTTP, IDL, MIME Sniffing, Streams, and URL Standards. [ABNF] [ENCODING] [HTML] [HTTP] [WEBIDL] [MIMESNIFF] [STREAMS] [URL]
ABNF
means
ABNF
as
modified
by
HTTP
(in
particular
the
addition
#
).
Credentials are HTTP cookies, TLS client certificates, and authentication entries (for HTTP authentication). [COOKIES] [TLS] [HTTP-AUTH]
Tasks that are queued by this standard are annotated as one of:
- process request body
- process request end-of-body
- process response
- process response end-of-body
- process response done
To queue a fetch task on request request to run an operation , run these steps:
-
If request ’s client is null, terminate these steps.
-
Queue a task to run an operation on request ’s client ’s responsible event loop using the networking task source .
To queue a fetch-request-done task , given a request , queue a fetch task on request to process request end-of-body for request .
2.1. URL
A
local
scheme
is
a
scheme
that
is
"
about
",
"
blob
",
"
data
",
or
"
filesystem
".
A URL is local if its scheme is a local scheme .
This definition is also used by Referrer Policy . [REFERRER]
An
HTTP(S)
scheme
is
a
scheme
that
is
"
http
"
or
"
https
".
A
network
scheme
is
a
scheme
that
is
"
ftp
"
or
an
HTTP(S)
scheme
.
A
fetch
scheme
is
a
scheme
that
is
"
about
",
"
blob
",
"
data
",
"
file
",
"
filesystem
",
or
a
network
scheme
.
HTTP(S) scheme , network scheme , and fetch scheme are also used by HTML . [HTML]
A response URL is a URL for which implementations need not store the fragment as it is never exposed. When serialized , the exclude fragment flag is set, meaning implementations can store the fragment nonetheless.
2.2. HTTP
While
fetching
encompasses
more
than
just
HTTP,
it
borrows
a
number
of
concepts
from
HTTP
and
applies
these
to
resources
obtained
via
other
means
(e.g.,
data
URLs).
The HTTP whitespace bytes are 0x09, 0x0A, 0x0D, and 0x20.
An
HTTPS
state
value
is
"
none
",
"
deprecated
",
or
"
modern
".
A
response
delivered
over
HTTPS
will
typically
have
its
HTTPS
state
set
to
"
modern
".
A
user
agent
can
use
"
deprecated
"
in
a
transition
period.
E.g.,
while
removing
support
for
a
hash
function,
weak
cipher
suites,
certificates
for
an
"Internal
Name",
or
certificates
with
an
overly
long
validity
period.
How
exactly
a
user
agent
can
use
"
deprecated
"
is
not
defined
by
this
specification.
An
environment
settings
object
typically
derives
its
HTTPS
state
from
a
response
.
2.2.1. Methods
A method is a byte sequence that matches the method token production.
A
CORS-safelisted
method
is
a
method
that
is
`
GET
`,
`
HEAD
`,
or
`
POST
`.
A
forbidden
method
is
a
method
that
is
a
byte-case-insensitive
match
for
`
CONNECT
`,
`
TRACE
`,
or
`
TRACK
`.
[HTTPVERBSEC1]
,
[HTTPVERBSEC2]
,
[HTTPVERBSEC3]
To
normalize
a
method
,
if
it
is
a
byte-case-insensitive
match
for
`
DELETE
`,
`
GET
`,
`
HEAD
`,
`
OPTIONS
`,
`
POST
`,
or
`
PUT
`,
byte-uppercase
it.
Normalization is done for backwards compatibility and consistency across APIs as methods are actually "case-sensitive".
Using
`
patch
`
is
highly
likely
to
result
in
a
`
405
Method
Not
Allowed
`.
`
PATCH
`
is
much
more
likely
to
succeed.
There
are
no
restrictions
on
methods
.
`
CHICKEN
`
is
perfectly
acceptable
(and
not
a
misspelling
of
`
CHECKIN
`).
Other
than
those
that
are
normalized
there
are
no
casing
restrictions
either.
`
Egg
`
or
`
eGg
`
would
be
fine,
though
uppercase
is
encouraged
for
consistency.
2.2.2. Headers
A header list is a list of zero or more headers . It is initially the empty list.
A header list is essentially a specialized multimap. An ordered list of key-value pairs with potentially duplicate keys.
A header list ( list ) contains a name ( name ) if list contains a header whose name is a byte-case-insensitive match for name .
To append a name / value ( name / value ) pair to a header list ( list ), run these steps:
-
If list contains name , then set name to the first such header ’s name .
This reuses the casing of the name of the header already in list , if any. If there are multiple matched headers their names will all be identical.
-
Append a new header whose name is name and value is value to list .
To delete a name ( name ) from a header list ( list ), remove all headers whose name is a byte-case-insensitive match for name from list .
To set a name / value ( name / value ) pair in a header list ( list ), run these steps:
-
If list contains name , then set the value of the first such header to value and remove the others.
-
Otherwise, append a new header whose name is name and value is value to list .
To combine a name / value ( name / value ) pair in a header list ( list ), run these steps:
-
If list contains name , then set the value of the first such header to its value , followed by 0x2C 0x20, followed by value .
-
Otherwise, append a new header whose name is name and value is value to list .
Combine
is
used
by
XMLHttpRequest
and
the
WebSocket
protocol
handshake
.
To sort and combine a header list ( list ), run these steps:
-
Let headers be an empty list of name - value pairs with the key being the name and value the value .
-
Let names be all the names of the headers in list , byte-lowercased , with duplicates removed, and finally sorted lexicographically.
-
For each name in names :
-
Let value be the combined value given name and list .
-
Append name - value to headers .
-
-
Return headers .
A header consists of a name and value .
A name is a byte sequence that matches the field-name token production.
A value is a byte sequence that matches the following conditions:
-
Has no leading or trailing HTTP whitespace bytes .
-
Contains no 0x00, 0x0A or 0x0D bytes.
The definition of value is not defined in terms of an HTTP token production as it is broken .
To normalize a potentialValue , remove any leading and trailing HTTP whitespace bytes from potentialValue .
A combined value , given a name ( name ) and header list ( list ), is the values of all headers in list whose name is a byte-case-insensitive match for name , separated from each other by 0x2C 0x20, in order.
A CORS-safelisted request-header is a header whose name is a byte-case-insensitive match for one of
-
`
Accept
` -
`
Accept-Language
` -
`
Content-Language
` -
`
Content-Type
` and whose value , once extracted , has a MIME type (ignoring parameters) that is `application/x-www-form-urlencoded
`, `multipart/form-data
`, or `text/plain
`
or whose name is a byte-case-insensitive match for one of
-
`
DPR
` -
`
Downlink
` -
`
Save-Data
` -
`
Viewport-Width
` -
`
Width
`
and whose value , once extracted , is not failure.
There
are
limited
exceptions
to
the
`
Content-Type
`
header
safelist,
as
documented
in
CORS
protocol
exceptions
.
A
CORS
non-wildcard
request-header
name
is
a
byte-case-insensitive
match
for
`
Authorization
`.
A CORS-safelisted response-header name , given a CORS-exposed header-name list list , is a header name that is a byte-case-insensitive match for one of
-
`
Cache-Control
` -
`
Content-Language
` -
`
Content-Length
` -
`
Content-Type
` -
`
Expires
` -
`
Last-Modified
` -
`
Pragma
` - Any value in list that is not a forbidden response-header name .
A forbidden header name is a header name that is a byte-case-insensitive match for one of
-
`
Accept-Charset
` -
`
Accept-Encoding
` -
`
Access-Control-Request-Headers
` -
`
Access-Control-Request-Method
` -
`
Connection
` -
`
Content-Length
` -
`
Cookie
` -
`
Cookie2
` -
`
Date
` -
`
DNT
` -
`
Expect
` -
`
Host
` -
`
Keep-Alive
` -
`
Origin
` -
`
Referer
` -
`
TE
` -
`
Trailer
` -
`
Transfer-Encoding
` -
`
Upgrade
` -
`
Via
`
or
a
header
name
that
starts
with
a
byte-case-insensitive
match
for
`
Proxy-
`
or
`
Sec-
`
(including
being
a
byte-case-insensitive
match
for
just
`
Proxy-
`
or
`
Sec-
`).
These
are
forbidden
so
the
user
agent
remains
in
full
control
over
them.
Names
starting
with
`
Sec-
`
are
reserved
to
allow
new
headers
to
be
minted
that
are
safe
from
APIs
using
fetch
that
allow
control
over
headers
by
developers,
such
as
XMLHttpRequest
.
[XHR]
A forbidden response-header name is a header name that is a byte-case-insensitive match for one of:
-
`
Set-Cookie
` -
`
Set-Cookie2
`
To extract header values given a header header , run these steps:
-
If parsing header ’s value , per the ABNF for header ’s name , fails, then return failure.
-
Return one or more values resulting from parsing header ’s value , per the ABNF for header ’s name .
To extract header list values given a name ( name ) and a header list ( list ), run these steps:
-
If list does not contain name , then return null.
-
If the ABNF for name allows a single header and list contains more than one, then return failure.
If different error handling is needed, extract the desired header first.
-
Let values be an empty list .
-
For each header header list contains whose name is name :
-
Let extract be the result of extracting header values from header .
-
If extract is failure, then return failure.
-
Append each value in extract , in order, to values .
-
-
Return values .
To extract a MIME type from a header list ( headers ), run these steps:
-
Let mimeType be the result of extracting header list values given `
Content-Type
` and headers . -
If mimeType is null or failure, then return the empty byte sequence.
-
Return mimeType , byte-lowercased .
A
default
`
User-Agent
`
value
is
a
user-agent-defined
value
for
the
`
User-Agent
`
header
.
2.2.3. Statuses
A status is a code.
A
null
body
status
is
a
status
that
is
101
,
204
,
205
,
or
304
.
An
ok
status
is
any
status
in
the
range
200
to
299
,
inclusive.
A
redirect
status
is
a
status
that
is
301
,
302
,
303
,
307
,
or
308
.
2.2.4. Bodies
A body consists of:
-
A stream (null or a
ReadableStream
object). -
A transmitted bytes (an integer), initially 0.
-
A total bytes (an integer), initially 0.
-
A source , initially null.
A body body is said to be done if body is null or body ’s stream is closed or errored .
To wait for a body body , wait for body to be done .
To clone a body body , run these steps:
-
Let « out1 , out2 » be the result of teeing body ’s stream .
-
Set body ’s stream to out1 .
-
Return a body whose stream is out2 and other members are copied from body .
To handle content codings given codings and bytes , run these steps:
-
If codings are not supported, then return bytes .
-
Return the result of decoding bytes with codings as explained in HTTP, if decoding does not result in an error, and failure otherwise. [HTTP] [HTTP-SEMANTICS]
2.2.5. Requests
The input to fetch is a request .
A
request
has
an
associated
method
(a
method
).
Unless
stated
otherwise
it
is
`
GET
`.
This
can
be
updated
during
redirects
to
`
GET
`
as
described
in
HTTP
fetch
.
A request has an associated url (a URL ).
Implementations are encouraged to make this a pointer to the first URL in request ’s url list . It is provided as a distinct field solely for the convenience of other standards hooking into Fetch.
A request has an associated local-URLs-only flag . Unless stated otherwise it is unset.
A request has an associated sandboxed-storage-area-URLs flag . Unless stated otherwise it is unset.
A request has an associated header list (a header list ). Unless stated otherwise it is empty.
A request has an associated unsafe-request flag . Unless stated otherwise it is unset.
The
unsafe-request
flag
is
set
by
APIs
such
as
fetch()
and
XMLHttpRequest
to
ensure
a
CORS-preflight
fetch
is
done
based
on
the
supplied
method
and
header
list
.
It
does
not
free
an
API
from
outlawing
forbidden
methods
and
forbidden
header
names
.
A request has an associated body (null or a body ). Unless stated otherwise it is null.
This can be updated during redirects to null as described in HTTP fetch .
A request has an associated client (null or an environment settings object ).
A request has an associated reserved client (null, an environment , or an environment settings object ). Unless stated otherwise it is null.
This is only used by navigation requests and worker requests, but not service worker requests. It references an environment for a navigation request and an environment settings object for a worker request.
A request has an associated target client id (a string). Unless stated otherwise it is the empty string.
This is only used by navigation requests . It is the id of the target browsing context ’s active document ’s environment settings object .
A
request
has
an
associated
window
("
no-window
",
"
client
",
or
an
environment
settings
object
whose
global
object
is
a
Window
object).
Unless
stated
otherwise
it
is
"
client
".
The
"
client
"
value
is
changed
to
"
no-window
"
or
request
’s
client
during
fetching
.
It
provides
a
convenient
way
for
standards
to
not
have
to
explicitly
set
request
’s
window
.
A request has an associated keepalive flag . Unless stated otherwise it is unset.
This
can
be
used
to
allow
the
request
to
outlive
the
environment
settings
object
,
e.g.,
navigator.sendBeacon
and
the
HTML
img
element
set
this
flag.
Requests
with
this
flag
set
are
subject
to
additional
processing
requirements.
A
request
has
an
associated
service-workers
mode
,
that
is
"
all
"
or
"
none
".
Unless
stated
otherwise
it
is
"
all
".
This
determines
which
service
workers
will
receive
a
fetch
event
for
this
fetch.
-
"
all
" -
Relevant
service
workers
will
get
a
fetch
event for this fetch. -
"
none
" - No service workers will get events for this fetch.
A
request
has
an
associated
initiator
,
which
is
the
empty
string,
"
download
",
"
imageset
",
"
manifest
",
"
prefetch
",
"
prerender
",
or
"
xslt
".
Unless
stated
otherwise
it
is
the
empty
string.
A request ’s initiator is not particularly granular for the time being as other specifications do not require it to be. It is primarily a specification device to assist defining CSP and Mixed Content. It is not exposed to JavaScript. [CSP] [MIX]
A
request
has
an
associated
destination
,
which
is
the
empty
string,
"
audio
",
"
audioworklet
",
"
document
",
"
embed
",
"
font
",
"
image
",
"
manifest
",
"
object
",
"
paintworklet
",
"
report
",
"
script
",
"
serviceworker
",
"
sharedworker
",
"
style
",
"
track
",
"
video
",
"
worker
",
or
"
xslt
".
Unless
stated
otherwise
it
is
the
empty
string.
A
request
’s
destination
is
script-like
if
it
is
"
audioworklet
",
"
paintworklet
",
"
script
",
"
serviceworker
",
"
sharedworker
",
or
"
worker
".
Algorithms
that
use
script-like
should
also
consider
"
xslt
"
as
that
too
can
cause
script
execution.
It
is
not
included
in
the
list
as
it
is
not
always
relevant
and
might
require
different
behavior.
The following table illustrates the relationship between a request ’s initiator , destination , CSP directives, and features. It is not exhaustive with respect to features. Features need to have the relevant values defined in their respective standards.
Initiator | Destination | CSP directive | Features |
---|---|---|---|
"" |
"
report
"
| — | CSP, NEL reports. |
"
document
"
| HTML’s navigate algorithm. | ||
"
document
"
|
child-src
|
HTML’s
<iframe>
and
<frame>
| |
"" |
connect-src
|
navigator.sendBeacon()
,
EventSource
,
HTML’s
ping=""
,
fetch()
,
XMLHttpRequest
,
WebSocket
,
Cache
API?
| |
"
object
"
|
object-src
|
HTML’s
<object>
| |
"
embed
"
|
object-src
|
HTML’s
<embed>
| |
"
audio
"
|
media-src
|
HTML’s
<audio>
| |
"
font
"
|
font-src
|
CSS'
@font-face
| |
"
image
"
|
img-src
|
HTML’s
<img
src>
,
/favicon.ico
resource,
SVG’s
<image>
,
CSS'
background-image
,
CSS'
cursor
,
CSS'
list-style-image
,
…
| |
"
audioworklet
"
|
script-src
|
audioWorklet.addModule()
| |
"
paintworklet
"
|
script-src
|
CSS.paintWorklet.addModule()
| |
"
script
"
|
script-src
|
HTML’s
<script>
,
importScripts()
| |
"
serviceworker
"
|
child-src
,
script-src
,
worker-src
|
navigator.serviceWorker.register()
| |
"
sharedworker
"
|
child-src
,
script-src
,
worker-src
|
SharedWorker
| |
"
worker
"
|
child-src
,
script-src
,
worker-src
|
Worker
| |
"
style
"
|
style-src
|
HTML’s
<link
rel=stylesheet>
,
CSS'
@import
| |
"
track
"
|
media-src
|
HTML’s
<track>
| |
"
video
"
|
media-src
|
HTML’s
<video>
element
| |
"
download
"
| "" | — |
HTML’s
download=""
,
"Save
Link
As…"
UI
|
"
imageset
"
|
"
image
"
|
img-src
|
HTML’s
<img
srcset>
and
<picture>
|
"
manifest
"
|
"
manifest
"
|
manifest-src
|
HTML’s
<link
rel=manifest>
|
"
prefetch
"
| "" |
prefetch-src
|
HTML’s
<link
rel=prefetch>
|
"
prerender
"
|
HTML’s
<link
rel=prerender>
| ||
"
xslt
"
|
"
xslt
"
|
script-src
|
<?xml-stylesheet>
|
CSP’s
form-action
needs
to
be
a
hook
directly
in
HTML’s
navigate
or
form
submission
algorithm.
CSP will also need to check request ’s client ’s responsible browsing context ’s ancestor browsing contexts for various CSP directives.
A request has an associated priority (null or a user-agent-defined object). Unless otherwise stated it is null.
A
request
has
an
associated
origin
,
which
is
"
client
"
or
an
origin
.
Unless
stated
otherwise
it
is
"
client
".
"
client
"
is
changed
to
an
origin
during
fetching
.
It
provides
a
convenient
way
for
standards
to
not
have
to
set
request
’s
origin
.
A
request
has
an
associated
referrer
,
which
is
"
no-referrer
",
"
client
",
or
a
URL
.
Unless
stated
otherwise
it
is
"
client
".
"
client
"
is
changed
to
"
no-referrer
"
or
a
URL
during
fetching
.
It
provides
a
convenient
way
for
standards
to
not
have
to
set
request
’s
referrer
.
A request has an associated referrer policy , which is a referrer policy . Unless stated otherwise it is the empty string. [REFERRER]
This can be used to override a referrer policy associated with an environment settings object .
A request has an associated client hints list , which is a client-hints list . Unless stated otherwise, it is the empty list.
This will be used to override a client hints list associated with an environment settings object . [CLIENT-HINTS]
A request has an associated synchronous flag . Unless stated otherwise it is unset.
A
request
has
an
associated
mode
,
which
is
"
same-origin
",
"
cors
",
"
no-cors
",
"
navigate
",
or
"
websocket
".
Unless
stated
otherwise,
it
is
"
no-cors
".
-
"
same-origin
" - Used to ensure requests are made to same-origin URLs. Fetch will return a network error if the request is not made to a same-origin URL.
-
"
cors
" - Makes the request a CORS request . Fetch will return a network error if the requested resource does not understand the CORS protocol .
-
"
no-cors
" - Restricts requests to using CORS-safelisted methods and CORS-safelisted request-headers . Upon success, fetch will return an opaque filtered response .
-
"
navigate
" - This is a special mode used only when navigating between documents.
-
"
websocket
" - This is a special mode used only when establishing a WebSocket connection .
Even
though
the
default
request
mode
is
"
no-cors
",
standards
are
highly
discouraged
from
using
it
for
new
features.
It
is
rather
unsafe.
A request has an associated use-CORS-preflight flag . Unless stated otherwise, it is unset.
The
use-CORS-preflight
flag
being
set
is
one
of
several
conditions
that
results
in
a
CORS-preflight
request
.
The
use-CORS-preflight
flag
is
set
if
either
one
or
more
event
listeners
are
registered
on
an
XMLHttpRequestUpload
object
or
if
a
ReadableStream
object
is
used
in
a
request.
A
request
has
an
associated
credentials
mode
,
which
is
"
omit
",
"
same-origin
",
or
"
include
".
Unless
stated
otherwise,
it
is
"
omit
".
-
"
omit
" - Excludes credentials from this request.
-
"
same-origin
" - Include credentials with requests made to same-origin URLs.
-
"
include
" - Always includes credentials with this request.
Request
’s
credentials
mode
controls
the
flow
of
credentials
during
a
fetch
.
When
request
’s
mode
is
"
navigate
",
its
credentials
mode
is
assumed
to
be
"
include
"
and
fetch
does
not
currently
account
for
other
values.
If
HTML
changes
here,
this
standard
will
need
corresponding
changes.
A request has an associated use-URL-credentials flag . Unless stated otherwise, it is unset.
A
request
has
an
associated
cache
mode
,
which
is
"
default
",
"
no-store
",
"
reload
",
"
no-cache
",
"
force-cache
",
or
"
only-if-cached
".
Unless
stated
otherwise,
it
is
"
default
".
-
"
default
" - Fetch will inspect the HTTP cache on the way to the network. If there is a fresh response it will be used. If there is a stale response a conditional request will be created, and a normal request otherwise. It then updates the HTTP cache with the response. [HTTP] [HTTP-SEMANTICS] [HTTP-COND] [HTTP-CACHING] [HTTP-AUTH]
-
"
no-store
" - Fetch behaves as if there is no HTTP cache at all.
-
"
reload
" - Fetch behaves as if there is no HTTP cache on the way to the network. Ergo, it creates a normal request and updates the HTTP cache with the response.
-
"
no-cache
" - Fetch creates a conditional request if there is a response in the HTTP cache and a normal request otherwise. It then updates the HTTP cache with the response.
-
"
force-cache
" - Fetch uses any response in the HTTP cache matching the request, not paying attention to staleness. If there was no response, it creates a normal request and updates the HTTP cache with the response.
-
"
only-if-cached
" -
Fetch
uses
any
response
in
the
HTTP
cache
matching
the
request,
not
paying
attention
to
staleness.
If
there
was
no
response,
it
returns
a
network
error.
(Can
only
be
used
when
request
’s
mode
is
"
same-origin
". Any cached redirects will be followed assuming request ’s redirect mode is "follow
" and the redirects do not violate request ’s mode .)
If
header
list
contains
`
If-Modified-Since
`,
`
If-None-Match
`,
`
If-Unmodified-Since
`,
`
If-Match
`,
or
`
If-Range
`,
fetch
will
set
cache
mode
to
"
no-store
"
if
it
is
"
default
".
A
request
has
an
associated
redirect
mode
,
which
is
"
follow
",
"
error
",
or
"
manual
".
Unless
stated
otherwise,
it
is
"
follow
".
-
"
follow
" - Follow all redirects incurred when fetching a resource.
-
"
error
" - Return a network error when a request is met with a redirect.
-
"
manual
" - Retrieves an opaque-redirect filtered response when a request is met with a redirect so that the redirect can be followed manually.
A request has associated integrity metadata (a string). Unless stated otherwise, it is the empty string.
A request has associated cryptographic nonce metadata (a string). Unless stated otherwise, it is the empty string.
A
request
has
associated
parser
metadata
which
is
the
empty
string,
"
parser-inserted
",
or
"
not-parser-inserted
".
Unless
otherwise
stated,
it
is
the
empty
string.
A request ’s cryptographic nonce metadata and parser metadata are generally populated from attributes and flags on the HTML element responsible for creating a request . They are used by various algorithms in Content Security Policy to determine whether requests or responses are to be blocked in a given context. [CSP]
A request has an associated reload-navigation flag . Unless stated otherwise, it is unset.
This flag is for exclusive use by HTML’s navigate algorithm. [HTML]
A request has an associated tainted origin flag . Unless stated otherwise, it is unset.
A request has an associated url list (a list of one or more URLs ). Unless stated otherwise, it is a list containing a copy of request ’s url .
A request has an associated current url . It is a pointer to the last URL in request ’s url list .
A request has an associated redirect count . Unless stated otherwise, it is zero.
A
request
has
an
associated
response
tainting
,
which
is
"
basic
",
"
cors
",
or
"
opaque
".
Unless
stated
otherwise,
it
is
"
basic
".
A request has an associated done flag . Unless stated otherwise, it is unset.
A request ’s tainted origin flag , url list , current url , redirect count , response tainting , and done flag are used as bookkeeping details by the fetch algorithm.
A
subresource
request
is
a
request
whose
destination
is
"
audio
",
"
audioworklet
",
"
font
",
"
image
",
"
manifest
",
"
paintworklet
",
"
script
",
"
style
",
"
track
",
"
video
",
"
xslt
",
or
the
empty
string.
A
potential-navigation-or-subresource
request
is
a
request
whose
destination
is
"
object
"
or
"
embed
".
A
non-subresource
request
is
a
request
whose
destination
is
"
document
",
"
report
",
"
serviceworker
",
"
sharedworker
",
or
"
worker
".
A
navigation
request
is
a
request
whose
destination
is
"
document
".
See handle fetch for usage of these terms. [SW]
Serializing a request origin , given a request request , is to run these steps:
-
If request ’s tainted origin flag is set, then return `
null
`. -
Return request ’s origin , serialized and isomorphic encoded .
To clone a request request , run these steps:
-
Let newRequest be a copy of request , except for its body .
-
If request ’s body is non-null, set newRequest ’s body to the result of cloning request ’s body .
-
Return newRequest .
To transmit body for a request request , run these steps:
- Let body be request ’s body .
-
If body is null, then queue a fetch task on request to process request end-of-body for request and abort these steps.
-
Let reader be the result of getting a reader from body ’s stream .
This operation cannot throw an exception.
-
Let read be the result of reading a chunk from body ’s stream with reader .
-
In parallel , while true:
-
Run these steps, but abort when the ongoing fetch is terminated :
-
Wait for read to be fulfilled or rejected.
-
If read is fulfilled with an object whose
done
property is false and whosevalue
property is aUint8Array
object, then run these steps:-
Let bs be the byte sequence represented by the
Uint8Array
object. -
Transmit bs . Whenever one or more bytes are transmitted, increase body ’s transmitted bytes by the number of transmitted bytes and queue a fetch task on request to process request body for request .
This step blocks until bs is fully transmitted.
-
Set read to the result of reading a chunk from body ’s stream with reader .
-
-
Otherwise, if read is fulfilled with an object whose
done
property is true, then queue a fetch task on request to process request end-of-body for request and abort these in-parallel steps. -
Otherwise, if read is rejected with an "
AbortError
"DOMException
, terminate the ongoing fetch with the aborted flag set. -
Otherwise, terminate the ongoing fetch.
-
-
If aborted , then abort these in-parallel steps.
-
2.2.6. Responses
The result of fetch is a response . A response evolves over time. That is, not all its fields are available straight away.
A
response
has
an
associated
type
which
is
"
basic
",
"
cors
",
"
default
",
"
error
",
"
opaque
",
or
"
opaqueredirect
".
Unless
stated
otherwise,
it
is
"
default
".
A response can have an associated aborted flag , which is initially unset.
This indicates that the request was intentionally aborted by the developer or end-user.
A response has an associated url . It is a pointer to the last response URL in response ’s url list and null if response ’s url list is the empty list.
A response has an associated url list (a list of zero or more response URLs ). Unless stated otherwise, it is the empty list.
Except for the last response URL , if any, a response ’s url list cannot be exposed to script. That would violate atomic HTTP redirect handling .
A
response
has
an
associated
status
,
which
is
a
status
.
Unless
stated
otherwise
it
is
200
.
A response has an associated status message . Unless stated otherwise it is the empty byte sequence.
Responses over an HTTP/2 connection will always have the empty byte sequence as status message as HTTP/2 does not support them.
A response has an associated header list (a header list ). Unless stated otherwise it is empty.
A response has an associated body (null or a body ). Unless stated otherwise it is null.
A response has an associated trailer (a header list ). Unless stated otherwise it is empty.
A response has an associated trailer failed flag , which is initially unset.
A
response
has
an
associated
cache
state
(the
empty
string
or
"
local
").
Unlesss
stated
otherwise,
it
is
the
empty
string.
This is intended solely for usage by service workers. [SW]
A
response
has
an
associated
HTTPS
state
(an
HTTPS
state
value
).
Unless
stated
otherwise,
it
is
"
none
".
A response has an associated CSP list , which is a list of Content Security Policy objects for the response . The list is empty unless otherwise specified. [CSP]
A response has an associated CORS-exposed header-name list (a list of zero or more header names ). The list is empty unless otherwise specified.
A
response
will
typically
get
its
CORS-exposed
header-name
list
set
by
extracting
header
values
from
the
`
Access-Control-Expose-Headers
`
header.
This
list
is
used
by
a
CORS
filtered
response
to
determine
which
headers
to
expose.
A response can have an associated location URL (null, failure, or a URL ). Unless specified otherwise, response has no location URL .
This
concept
is
used
for
redirect
handling
in
Fetch
and
in
HTML’s
navigate
algorithm.
It
ensures
`
Location
`
has
its
value
extracted
consistently
and
only
once.
[HTML]
A
response
whose
type
is
"
error
"
and
aborted
flag
is
set
is
known
as
an
aborted
network
error
.
A
response
whose
type
is
"
error
"
is
known
as
a
network
error
.
A
network
error
is
a
response
whose
status
is
always
0
,
status
message
is
always
the
empty
byte
sequence,
header
list
is
always
empty,
body
is
always
null,
and
trailer
is
always
empty.
A filtered response is a limited view on a response that is not a network error . This response is referred to as the filtered response ’s associated internal response .
The fetch algorithm returns such a view to ensure APIs do not accidentally leak information. If the information needs to be exposed for legacy reasons, e.g., to feed image data to a decoder, the associated internal response can be used, which is only "accessible" to internal specification algorithms and is never a filtered response itself.
A
basic
filtered
response
is
a
filtered
response
whose
type
is
"
basic
"
and
header
list
excludes
any
headers
in
internal
response
’s
header
list
whose
name
is
a
forbidden
response-header
name
.
A
CORS
filtered
response
is
a
filtered
response
whose
type
is
"
cors
",
header
list
excludes
any
headers
in
internal
response
’s
header
list
whose
name
is
not
a
CORS-safelisted
response-header
name
,
given
internal
response
’s
CORS-exposed
header-name
list
,
and
trailer
is
empty.
An
opaque
filtered
response
is
a
filtered
response
whose
type
is
"
opaque
",
url
list
is
the
empty
list,
status
is
0
,
status
message
is
the
empty
byte
sequence,
header
list
is
empty,
body
is
null,
and
trailer
is
empty.
An
opaque-redirect
filtered
response
is
a
filtered
response
whose
type
is
"
opaqueredirect
",
status
is
0
,
status
message
is
the
empty
byte
sequence,
header
list
is
empty,
body
is
null,
and
trailer
is
empty.
Exposing the url list for opaque-redirect filtered responses is harmless since no redirects are followed.
In other words, an opaque filtered response and an opaque-redirect filtered response are nearly indistinguishable from a network error . When introducing new APIs, do not use the internal response for internal specification algorithms as that will leak information.
This
also
means
that
JavaScript
APIs,
such
as
response.ok
,
will
return
rather
useless
results.
To clone a response response , run these steps:
-
If response is a filtered response , then return a new identical filtered response whose internal response is a clone of response ’s internal response .
-
Let newResponse be a copy of response , except for its body .
-
If response ’s body is non-null, then set newResponse ’s body to the result of cloning response ’s body .
-
Return newResponse .
2.2.7. Miscellaneous
A
potential
destination
is
"
fetch
"
or
a
destination
which
is
not
the
empty
string.
To translate a potential destination potentialDestination , run these steps:
-
If potentialDestination is "
fetch
", then return the empty string. -
Assert: potentialDestination is a destination .
-
Return potentialDestination .
2.3. Authentication entries
An authentication entry and a proxy-authentication entry are tuples of username, password, and realm, used for HTTP authentication and HTTP proxy authentication, and associated with one or more requests .
User agents should allow both to be cleared together with HTTP cookies and similar tracking functionality.
Further details are defined by HTTP. [HTTP] [HTTP-SEMANTICS] [HTTP-COND] [HTTP-CACHING] [HTTP-AUTH]
2.4. Fetch groups
Each environment settings object has an associated fetch group .
A fetch group holds an ordered list of fetch records .
A fetch record has an associated request (a request ).
A fetch record has an associated fetch (a fetch algorithm or null).
When a fetch group is terminated , for each associated fetch record whose request ’s done flag or keepalive flag is unset, terminate the fetch record ’s fetch .
2.5. Connections
A user agent has an associated connection pool . A connection pool consists of zero or more connections . Each connection is identified by an origin (an origin ) and credentials (a boolean).
To obtain a connection , given an origin and credentials , run these steps:
-
If connection pool contains a connection whose origin is origin and credentials is credentials , then return that connection .
-
Let connection be null.
-
Run these steps, but abort when the ongoing fetch is terminated :
-
Set connection to the result of establishing an HTTP connection to origin . [HTTP] [HTTP-SEMANTICS] [HTTP-COND] [HTTP-CACHING] [HTTP-AUTH] [TLS]
If credentials is false, then do not send a TLS client certificate.
If establishing a connection does not succeed (e.g., a DNS, TCP, or TLS error), then return failure.
-
-
If aborted , then:
-
If connection is not null, then close connection .
-
Return failure.
-
-
Add connection to the connection pool with origin being origin and credentials being credentials .
-
Return connection .
This
is
intentionally
a
little
vague
as
the
finer
points
are
still
evolving.
Describing
this
helps
explain
the
<link
rel=preconnect>
feature
and
clearly
stipulates
that
connections
are
keyed
on
credentials
.
The
latter
clarifies
that
e.g.,
TLS
session
identifiers
are
not
reused
across
connections
whose
credentials
are
false
with
connections
whose
credentials
are
true.
2.6. Port blocking
To determine whether fetching a request request should be blocked due to a bad port , run these steps:
-
Let url be request ’s current url .
-
Let scheme be url ’s scheme .
-
Let port be url ’s port .
-
If scheme is "
ftp
" and port is 20 or 21, then return allowed . -
Otherwise, if scheme is a network scheme and port is a bad port , then return blocked .
-
Return allowed .
A port is a bad port if it is listed in the first column of the following table.
Port | Typical service |
---|---|
1 | tcpmux |
7 | echo |
9 | discard |
11 | systat |
13 | daytime |
15 | netstat |
17 | qotd |
19 | chargen |
20 | ftp-data |
21 | ftp |
22 | ssh |
23 | telnet |
25 | smtp |
37 | time |
42 | name |
43 | nicname |
53 | domain |
77 | priv-rjs |
79 | finger |
87 | ttylink |
95 | supdup |
101 | hostriame |
102 | iso-tsap |
103 | gppitnp |
104 | acr-nema |
109 | pop2 |
110 | pop3 |
111 | sunrpc |
113 | auth |
115 | sftp |
117 | uucp-path |
119 | nntp |
123 | ntp |
135 | loc-srv / epmap |
139 | netbios |
143 | imap2 |
179 | bgp |
389 | ldap |
465 | smtp+ssl |
512 | print / exec |
513 | login |
514 | shell |
515 | printer |
526 | tempo |
530 | courier |
531 | chat |
532 | netnews |
540 | uucp |
556 | remotefs |
563 | nntp+ssl |
587 | smtp |
601 | syslog-conn |
636 | ldap+ssl |
993 | ldap+ssl |
995 | pop3+ssl |
2049 | nfs |
3659 | apple-sasl |
4045 | lockd |
6000 | x11 |
6665 | irc (alternate) |
6666 | irc (alternate) |
6667 | irc (default) |
6668 | irc (alternate) |
6669 | irc (alternate) |
2.7. Should response to request be blocked due to its MIME type?
Run these steps:
-
Let mimeType be the result of extracting a MIME type from response ’s header list .
-
Let destination be request ’s destination .
-
If destination is script-like and one of the following is true, then return blocked :
-
mimeType
starts
with
`
audio/
`, `image/
`, or `video/
`. -
mimeType
is
`
text/csv
`.
-
mimeType
starts
with
`
-
Return allowed .
2.8. Client hints list
This section will be integrated into HTTP Client Hints. [CLIENT-HINTS]
A
client
hints
list
is
a
list
of
Client
hint
tokens
,
each
of
which
is
one
of
`
DPR
`,
`
Save-Data
`,
`
Viewport-Width
`,
or
`
Width
`.
2.9. Streams
This section might be integrated into other standards, such as IDL.
2.9.1. ReadableStream
A
ReadableStream
object
represents
a
stream
of
data
.
In
this
section,
we
define
common
operations
for
ReadableStream
objects.
[STREAMS]
To
enqueue
chunk
into
a
ReadableStream
object
stream
,
run
these
steps:
-
Call ReadableStreamDefaultControllerEnqueue ( stream .[[readableStreamController]], chunk ).
To
close
a
ReadableStream
object
stream
,
run
these
steps:
-
Call ReadableStreamDefaultControllerClose ( stream .[[readableStreamController]]).
To
error
a
ReadableStream
object
stream
with
given
reason
,
run
these
steps:
-
Call ReadableStreamDefaultControllerError ( stream .[[readableStreamController]]). reason ).
To
construct
a
ReadableStream
object
with
given
strategy
,
pull
action
and
cancel
action,
all
of
which
are
optional,
run
these
steps:
-
Let init be a new object.
-
Set init ["pull"] to a function that runs pull if pull is given.
-
Set init ["cancel"] to a function that runs cancel if cancel is given.
-
Let stream be the result of calling the initial value of
ReadableStream
as constructor with init and strategy if given. -
Return stream .
To
construct
a
fixed
ReadableStream
object
with
given
chunks
,
run
these
steps:
-
Let stream be the result of constructing a
ReadableStream
object. -
For each chunk in chunks , enqueue chunk into stream .
-
Close stream .
- Return stream .
To
get
a
reader
from
a
ReadableStream
object
stream
,
run
these
steps:
-
Let reader be the result of calling AcquireReadableStreamDefaultReader ( stream ).
-
Return reader .
To
read
a
chunk
from
a
ReadableStream
object
with
reader
,
return
the
result
of
calling
ReadableStreamDefaultReaderRead
(
reader
).
To
read
all
bytes
from
a
ReadableStream
object
with
reader
,
run
these
steps:
-
Let promise be a new promise.
-
Let bytes be an empty byte sequence.
-
Let read be the result of calling ReadableStreamDefaultReaderRead ( reader ).
-
When read is fulfilled with an object whose
done
property is false and whosevalue
property is aUint8Array
object, append thevalue
property to bytes and run the above step again. -
When read is fulfilled with an object whose
done
property is true, resolve promise with bytes . -
When read is fulfilled with a value that matches with neither of the above patterns, reject promise with a
TypeError
. -
When read is rejected with an error, reject promise with that error.
-
-
Return promise .
To
cancel
a
ReadableStream
object
stream
with
reason
,
return
the
result
of
calling
ReadableStreamCancel
(
stream
,
reason
).
Because the reader grants exclusive access, the actual mechanism of how to read cannot be observed. Implementations could use more direct mechanism if convenient.
To
tee
a
ReadableStream
object
stream
,
run
these
steps:
-
Return the result of calling ReadableStreamTee ( stream , true).
An
empty
ReadableStream
object
is
the
result
of
constructing
a
fixed
ReadableStream
object
with
an
empty
list.
Constructing
an
empty
ReadableStream
object
will
not
throw
an
exception.
A
ReadableStream
object
stream
is
said
to
be
readable
if
stream
.[[state]]
is
"readable".
A
ReadableStream
object
stream
is
said
to
be
closed
if
stream
.[[state]]
is
"closed".
A
ReadableStream
object
stream
is
said
to
be
errored
if
stream
.[[state]]
is
"errored".
A
ReadableStream
object
stream
is
said
to
be
locked
if
the
result
of
calling
IsReadableStreamLocked
(
stream
)
is
true.
A
ReadableStream
object
stream
is
said
to
need
more
data
if
the
following
conditions
hold:
-
stream is readable .
-
The result of calling ReadableStreamDefaultControllerGetDesiredSize ( stream .[[readableStreamController]]). is positive.
A
ReadableStream
object
stream
is
said
to
be
disturbed
if
the
result
of
calling
IsReadableStreamDisturbed
(
stream
)
is
true.
3. HTTP extensions
3.1.
`
Origin
`
header
The
`
Origin
`
request
header
indicates
where
a
fetch
originates
from.
The
`
Origin
`
header
is
a
version
of
the
`
Referer
`
[sic]
header
that
does
not
reveal
a
path
.
It
is
used
for
all
HTTP
fetches
whose
CORS
flag
is
set
as
well
as
those
where
request
’s
method
is
neither
`
GET
`
nor
`
HEAD
`.
Due
to
compatibility
constraints
it
is
not
included
in
all
fetches
.
Origin = origin-or-null origin-or-null = origin / %x6E.75.6C.6C ; "null", case-sensitive origin = scheme "://" host [ ":" port ]
This
supplants
the
`
Origin
`
header
.
[ORIGIN]
3.2. CORS protocol
To
allow
sharing
responses
cross-origin
and
allow
for
more
versatile
fetches
than
possible
with
HTML’s
form
element,
the
CORS
protocol
exists.
It
is
layered
on
top
of
HTTP
and
allows
responses
to
declare
they
can
be
shared
with
other
origins
.
It needs to be an opt-in mechanism to prevent leaking data from responses behind a firewall (intranets). Additionally, for requests including credentials it needs to be opt-in to prevent leaking potentially-sensitive data.
This section explains the CORS protocol as it pertains to server developers. Requirements for user agents are part of the fetch algorithm, except for the new HTTP header syntax .
3.2.1. General
The CORS protocol consists of a set of headers that indicates whether a response can be shared cross-origin.
For
requests
that
are
more
involved
than
what
is
possible
with
HTML’s
form
element,
a
CORS-preflight
request
is
performed,
to
ensure
request
’s
current
url
supports
the
CORS
protocol
.
3.2.2. HTTP requests
A
CORS
request
is
an
HTTP
request
that
includes
an
`
Origin
`
header.
It
cannot
be
reliably
identified
as
participating
in
the
CORS
protocol
as
the
`
Origin
`
header
is
also
included
for
all
requests
whose
method
is
neither
`
GET
`
nor
`
HEAD
`.
A
CORS-preflight
request
is
a
CORS
request
that
checks
to
see
if
the
CORS
protocol
is
understood.
It
uses
`
OPTIONS
`
as
method
and
includes
these
headers
:
-
`
Access-Control-Request-Method
` -
Indicates which method a future CORS request to the same resource might use.
-
`
Access-Control-Request-Headers
` -
Indicates which headers a future CORS request to the same resource might use.
3.2.3. HTTP responses
An HTTP response to a CORS request can include the following headers :
-
`
Access-Control-Allow-Origin
` -
Indicates whether the response can be shared, via returning the literal value of the `
Origin
` request header (which can be `null
`) or `*
` in a response. -
`
Access-Control-Allow-Credentials
` -
Indicates whether the response can be shared when request ’s credentials mode is "
include
".For a CORS-preflight request , request ’s credentials mode is always "
omit
", but for any subsequent CORS requests it might not be. Support therefore needs to be indicated as part of the HTTP response to the CORS-preflight request as well.
An HTTP response to a CORS-preflight request can include the following headers :
-
`
Access-Control-Allow-Methods
` -
Indicates which methods are supported by the response ’s url for the purposes of the CORS protocol .
The `
Allow
` header is not relevant for the purposes of the CORS protocol . -
`
Access-Control-Allow-Headers
` -
Indicates which headers are supported by the response ’s url for the purposes of the CORS protocol .
-
`
Access-Control-Max-Age
` -
Indicates how long the information provided by the `
Access-Control-Allow-Methods
` and `Access-Control-Allow-Headers
` headers can be cached.
An HTTP response to a CORS request that is not a CORS-preflight request can also include the following header :
-
`
Access-Control-Expose-Headers
` -
Indicates which headers can be exposed as part of the response by listing their names .
In
case
a
server
does
not
wish
to
participate
in
the
CORS
protocol
,
its
HTTP
response
to
the
CORS
or
CORS-preflight
request
must
not
include
any
of
the
above
headers
.
The
server
is
encouraged
to
use
the
403
status
in
such
HTTP
responses.
3.2.4. HTTP new-header syntax
ABNF for the values of the headers used by the CORS protocol :
Access-Control-Request-Method = method Access-Control-Request-Headers = 1#field-name wildcard = "*" Access-Control-Allow-Origin = origin-or-null / wildcard Access-Control-Allow-Credentials = %x74.72.75.65 ; "true", case-sensitive Access-Control-Expose-Headers = #field-name Access-Control-Max-Age = delta-seconds Access-Control-Allow-Methods = #method Access-Control-Allow-Headers = # field-name
For
`
Access-Control-Expose-Headers
`,
`
Access-Control-Allow-Methods
`,
and
`
Access-Control-Allow-Headers
`
response
headers
the
value
`
*
`
counts
as
a
wildcard
for
requests
without
credentials
.
For
such
requests
there
is
no
way
to
solely
match
a
header
name
or
method
that
is
`
*
`.
3.2.5. CORS protocol and credentials
When
request
’s
credentials
mode
is
"
include
"
it
has
an
impact
on
the
functioning
of
the
CORS
protocol
other
than
including
credentials
in
the
fetch
.
In
the
old
days,
XMLHttpRequest
could
be
used
to
set
request
’s
credentials
mode
to
"
include
":
var client = new XMLHttpRequest() client.open("GET", "./") client.withCredentials = true /* … */
Nowadays,
fetch("./",
{
credentials:"include"
}).then(/*
…
*/)
suffices.
A request ’s credentials mode is not necessarily observable on the server; only when credentials exist for a request can it be observed by virtue of the credentials being included. Note that even so, a CORS-preflight request never includes credentials .
The server developer therefore needs to decide whether or not responses "tainted" with credentials can be shared. And also needs to decide if requests necessitating a CORS-preflight request can include credentials . Generally speaking, both sharing responses and allowing requests with credentials is rather unsafe, and extreme care has to be taken to avoid the confused deputy problem .
To
share
responses
with
credentials
,
the
`
Access-Control-Allow-Origin
`
and
`
Access-Control-Allow-Credentials
`
headers
are
important.
The
following
table
serves
to
illustrate
the
various
legal
and
illegal
combinations
for
a
request
to
https://rabbit.invalid/
:
Request’s credentials mode |
`
Access-Control-Allow-Origin
`
|
`
Access-Control-Allow-Credentials
`
| Shared? | Notes |
---|---|---|---|---|
"
omit
"
|
`
*
`
| Omitted | ✅ |
—
|
"
omit
"
|
`
*
`
|
`
true
`
| ✅ |
If
credentials
mode
is
not
"
include
",
then
`
Access-Control-Allow-Credentials
`
is
ignored.
|
"
omit
"
|
`
https://rabbit.invalid/`
| Omitted | ❌ | A serialized origin has no trailing slash. |
"
omit
"
|
`
https://rabbit.invalid`
| Omitted | ✅ |
—
|
"
include
"
|
`
*
`
|
`
true
`
| ❌ |
If
credentials
mode
is
"
include
",
then
`
Access-Control-Allow-Origin
`
cannot
be
`
*
`.
|
"
include
"
|
`
https://rabbit.invalid`
|
`
true
`
| ✅ |
—
|
"
include
"
|
`
https://rabbit.invalid`
|
`
True
`
| ❌ |
`
true
`
is
(byte)
case-sensitive.
|
Similarly,
`
Access-Control-Expose-Headers
`,
`
Access-Control-Allow-Methods
`,
and
`
Access-Control-Allow-Headers
`
response
headers
can
only
use
`
*
`
as
value
when
request
’s
credentials
mode
is
not
"
include
".
3.2.6. Examples
A
script
at
https://foo.invalid/
wants
to
fetch
some
data
from
https://bar.invalid/
.
(Neither
credentials
nor
response
header
access
is
important.)
var url = "https://bar.invalid/api?key=730d67a37d7f3d802e96396d00280768773813fbe726d116944d814422fc1a45&data=about:unicorn"; fetch(url).then(success, failure)
This
will
use
the
CORS
protocol
,
though
this
is
entirely
transparent
to
the
developer
from
foo.invalid
.
As
part
of
the
CORS
protocol
,
the
user
agent
will
include
the
`
Origin
`
header
in
the
request:
Origin: https://foo.invalid
Upon
receiving
a
response
from
bar.invalid
,
the
user
agent
will
verify
the
`
Access-Control-Allow-Origin
`
response
header.
If
its
value
is
either
`
https://foo.invalid
`
or
`
*
`,
the
user
agent
will
invoke
the
success
callback.
If
it
has
any
other
value,
or
is
missing,
the
user
agent
will
invoke
the
failure
callback.
The
developer
of
foo.invalid
is
back,
and
now
wants
to
fetch
some
data
from
bar.invalid
while
also
accessing
a
response
header.
fetch(url).then(response => { var hsts = response.headers.get("strict-transport-security"), csp = response.headers.get("content-security-policy") log(hsts, csp) })
bar.invalid
provides
a
correct
`
Access-Control-Allow-Origin
`
response
header
per
the
earlier
example.
The
values
of
hsts
and
csp
will
depend
on
the
`
Access-Control-Expose-Headers
`
response
header.
For
example,
if
the
response
included
the
following
headers
Content-Security-Policy: default-src 'self' Strict-Transport-Security: max-age=31536000; includeSubdomains; preload Access-Control-Expose-Headers: Content-Security-Policy
then
hsts
would
be
null
and
csp
would
be
"
default-src
'self'
",
even
though
the
response
did
include
both
headers.
This
is
because
bar.invalid
needs
to
explicitly
share
each
header
by
listing
their
names
in
the
`
Access-Control-Expose-Headers
`
response
header.
Alternatively,
if
bar.invalid
wanted
to
share
all
its
response
headers,
for
requests
that
do
not
include
credentials
,
it
could
use
`
*
`
as
value
for
the
`
Access-Control-Expose-Headers
`
response
header.
If
the
request
would
have
included
credentials
,
the
response
header
names
would
have
to
be
listed
explicitly
and
`
*
`
could
not
be
used.
The
developer
of
foo.invalid
returns,
now
fetching
some
data
from
bar.invalid
while
including
credentials
.
This
time
around
the
CORS
protocol
is
no
longer
transparent
to
the
developer
as
credentials
require
an
explicit
opt-in:
fetch(url, { credentials:"include" }).then(success, failure)
This
also
makes
any
`
Set-Cookie
`
response
headers
bar.invalid
includes
fully
functional
(they
are
ignored
otherwise).
The
user
agent
will
make
sure
to
include
any
relevant
credentials
in
the
request.
It
will
also
put
stricter
requirements
on
the
response.
Not
only
will
bar.invalid
need
to
list
`
https://foo.invalid
`
as
value
for
the
`
Access-Control-Allow-Origin
`
header
(`
*
`
is
not
allowed
when
credentials
are
involved),
the
`
Access-Control-Allow-Credentials
`
header
has
to
be
present
too:
Access-Control-Allow-Origin: https://foo.invalid Access-Control-Allow-Credentials: true
If
the
response
does
not
include
those
two
headers
with
those
values,
the
failure
callback
will
be
invoked
and
any
`
Set-Cookie
`
response
headers
will
end
up
being
ignored.
3.2.7. CORS protocol exceptions
Specifications
have
allowed
limited
exceptions
to
the
CORS
safelist
for
non-safelisted
`
Content-Type
`
header
values.
These
exceptions
are
made
for
requests
that
can
be
triggered
by
web
content
but
whose
headers
and
bodies
can
be
only
minimally
controlled
by
the
web
content.
Therefore,
servers
should
expect
cross-origin
web
content
to
be
allowed
to
trigger
non-preflighted
requests
with
the
following
non-safelisted
`
Content-Type
`
header
values:
-
`
application/csp-report
` [CSP] -
`
application/report
` [REPORTING] -
`
application/expect-ct-report+json
` [EXPECT-CT] -
`
application/xss-auditor-report
` -
`
application/ocsp-request
` [OCSP]
Specifications should avoid introducing new exceptions and should only do so with careful consideration for the security consequences. New exceptions can be proposed by filing an issue .
3.3.
`
X-Content-Type-Options
`
header
The
`
X-Content-Type-Options
`
response
header
can
be
used
to
require
checking
of
a
response
’s
`
Content-Type
`
header
against
the
destination
of
a
request
.
X-Content-Type-Options = "nosniff" ; case-insensitive
3.3.1. Should response to request be blocked due to nosniff?
Run these steps:
-
If response ’s header list does not contain `
X-Content-Type-Options
`, then return allowed . -
Let nosniff be the result of extracting header values from the first header whose name is a byte-case-insensitive match for `
X-Content-Type-Options
` in response ’s header list . -
If nosniff is failure, then return allowed .
-
Let mimeType be the result of extracting a MIME type from response ’s header list .
-
Let destination be request ’s destination .
-
If destination is script-like and mimeType (ignoring parameters) is not a JavaScript MIME type , then return blocked .
-
If destination is "
style
" and mimeType (ignoring parameters) is not `text/css
`, then return blocked . -
Return allowed .
Only
request
destinations
that
are
script-like
or
"
style
"
are
considered
as
any
exploits
pertain
to
them.
Also,
considering
"
image
"
was
not
compatible
with
deployed
content.
3.4. CORB
Cross-origin
read
blocking,
better
known
as
CORB,
is
an
algorithm
which
identifies
dubious
cross-origin
resource
fetches
(e.g.,
fetches
that
would
fail
anyway
like
attempts
to
render
JSON
inside
an
img
element)
and
blocks
them
before
they
reach
a
web
page.
CORB
reduces
the
risk
of
leaking
sensitive
data
by
keeping
it
further
from
cross-origin
web
pages.
A
CORB-protected
MIME
type
is
an
HTML
MIME
type
,
a
JSON
MIME
type
,
or
an
XML
MIME
type
excluding
image/svg+xml
.
Even
without
CORB,
accessing
the
content
of
cross-origin
resources
with
CORB-protected
MIME
types
is
either
managed
by
the
CORS
protocol
(e.g.,
in
case
of
XMLHttpRequest
),
not
observable
(e.g.,
in
case
of
pings
or
CSP
reports
which
ignore
the
response),
or
would
result
in
an
error
(e.g.,
when
failing
to
decode
an
HTML
document
embedded
in
an
img
element
as
an
image).
This
means
that
CORB
can
block
CORB-protected
MIME
types
resources
without
being
disruptive
to
web
pages.
To perform a CORB check , given a request and response , run these steps:
-
If request ’s initiator is "
download
", then return allowed .If we recast downloading as navigation this step can be removed.
-
If request ’s current url ’s scheme is not an HTTP(S) scheme , then return allowed .
-
Let mimeType be the result of extracting a MIME type from response ’s header list .
-
If response ’s status is
206
and mimeType (ignoring parameters) is a CORB-protected MIME type , then return blocked . -
Let nosniff be the result of extracting header values from the first header whose name is a byte-case-insensitive match for `
X-Content-Type-Options
` in response ’s header list . -
If nosniff is not failure and mimeType (ignoring parameters) is a CORB-protected MIME type or
text/plain
, then return blocked .CORB only protects
text/plain
responses with a `X-Content-Type-Options: nosniff
` header. Unfortunately, protecting such responses without that header when their status is206
would break too many existing video responses that have atext/plain
MIME type. -
Return allowed .
4. Fetching
The algorithm below defines fetching . In broad strokes, it takes a request and outputs a response .
That is, it either returns a response if request ’s synchronous flag is set, or it queues tasks annotated process response , process response end-of-body , and process response done for the response .
To capture uploads, if request ’s synchronous flag is unset, tasks annotated process request body and process request end-of-body for the request can be queued .
To perform a fetch using request , run the steps below. An ongoing fetch can be terminated with flag aborted , which is unset unless otherwise specified.
The user agent may be asked to suspend the ongoing fetch. The user agent may either accept or ignore the suspension request. The suspended fetch can be resumed . The user agent should ignore the suspension request if the ongoing fetch is updating the response in the HTTP cache for the request.
The
user
agent
does
not
update
the
entry
in
the
HTTP
cache
for
a
request
if
request’s
cache
mode
is
"no-store"
or
a
`
Cache-Control:
no-store
`
header
appears
in
the
response.
[HTTP-CACHING]
-
Run these steps, but abort when the ongoing fetch is terminated :
-
If request ’s window is "
client
", set request ’s window to request ’s client , if request ’s client ’s global object is aWindow
object, and to "no-window
" otherwise. -
If request ’s origin is "
client
", set request ’s origin to request ’s client ’s origin . -
If request ’s header list does not contain `
Accept
`, then:-
Let value be `
*/*
`. -
If request is a navigation request , a user agent should set value to `
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
`. -
Otherwise, a user agent should set value to the first matching statement, if any, switching on request ’s destination :
-
"
image
" -
`
image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5
` -
"
style
" -
`
text/css,*/*;q=0.1
`
-
"
-
Append `
Accept
`/ value to request ’s header list .
-
-
If request ’s header list does not contain `
Accept-Language
`, user agents should append `Accept-Language
`/an appropriate value to request ’s header list . -
If request ’s priority is null, then use request ’s initiator and destination appropriately in setting request ’s priority to a user-agent-defined object.
The user-agent-defined object could encompass stream weight and dependency for HTTP/2, and equivalent information used to prioritize dispatch and processing of HTTP/1 fetches.
-
If request is a navigation request , a user agent should, for each header name ( hintName ) in the first column of the following table, if request ’s header list does not contain hintName , then append hintName /the value given in the same row on the second column, to request ’s header list .
Name Value ` DPR
`a suitable dpr value ` Save-Data
`a suitable save-data value ` Viewport-Width
`a suitable viewport-width value -
If request is a subresource request , then:
-
For each hintName of request ’s client hints list :
-
Let value be the first matching statement, switching on hintName :
-
`
DPR
` - a suitable dpr value
-
`
Save-Data
` - a suitable save-data value
-
`
Viewport-Width
` - a suitable viewport-width value
-
`
Width
` - a suitable width value
-
`
-
A user agent should append hintName / value to request ’s header list .
-
-
Let record be a new fetch record consisting of request and this instance of the fetch algorithm.
-
Append record to request ’s client ’s fetch group list of fetch records .
-
-
-
If aborted , then:
-
Let aborted be the termination’s aborted flag.
-
If aborted is set, then return an aborted network error .
-
Return a network error .
-
-
Return the result of performing a main fetch using request .
4.1. Main fetch
To perform a main fetch using request , optionally with a CORS flag and recursive flag , run these steps:
When main fetch is invoked recursively recursive flag is set. CORS flag is a bookkeeping detail for handling redirects.
-
Let response be null.
-
Run these steps, but abort when the ongoing fetch is terminated :
-
If request ’s local-URLs-only flag is set and request ’s current url is not local , set response to a network error .
-
Execute Report Content Security Policy violations for request . [CSP]
-
Upgrade request to a potentially secure URL, if appropriate . [UPGRADE]
-
If should fetching request be blocked due to a bad port , should fetching request be blocked as mixed content , or should fetching request be blocked by Content Security Policy returns blocked , set response to a network error . [MIX] [CSP]
-
If request ’s referrer policy is the empty string and request ’s client is non-null, then set request ’s referrer policy to request ’s client ’s referrer policy . [REFERRER]
-
If request ’s referrer policy is the empty string, then set request ’s referrer policy to "
no-referrer-when-downgrade
".We use "
no-referrer-when-downgrade
" because it is the historical default. -
If request ’s referrer is not "
no-referrer
", set request ’s referrer to the result of invoking determine request ’s referrer . [REFERRER]As stated in Referrer Policy , user agents can provide the end user with options to override request ’s referrer to "
no-referrer
" or have it expose less sensitive information. -
If request ’s current URL ’s scheme is "
ftp
", request ’s client ’s creation URL ’s scheme is not "ftp
", and request ’s reserved client is either null or an environment whose target browsing context is a nested browsing context , then set response to a network error . -
Set request ’s current url ’s scheme to "
https
" if all of the following conditions are true:-
request
’s
current
url
’s
scheme
is
"
http
" - request ’s current url ’s host is a domain
-
Matching
request
’s
current
url
’s
host
per
Known
HSTS
Host
Domain
Name
Matching
results
in
either
a
superdomain
match
with
an
asserted
includeSubDomains
directive or a congruent match (with or without an assertedincludeSubDomains
directive) [HSTS]
-
request
’s
current
url
’s
scheme
is
"
-
-
If aborted , then:
-
Let aborted be the termination’s aborted flag.
-
If aborted is set, then return an aborted network error .
-
Return a network error .
-
-
If request ’s synchronous flag is unset and recursive flag is unset, run the remaining steps in parallel .
-
If response is null, then set response to the result of running the steps corresponding to the first matching statement:
-
request
’s
current
url
’s
origin
is
same
origin
with
request
’s
origin
and
CORS
flag
is
unset
- request ’s current url ’s scheme is "
data
"- request ’s mode is "
navigate
" or "websocket
" - request ’s current url ’s scheme is "
-
-
Set request ’s response tainting to "
basic
". -
Return the result of performing a scheme fetch using request .
HTML assigns any documents and workers created from URLs whose scheme is "
data
" a unique opaque origin . Service workers can only be created from URLs whose scheme is an HTTP(S) scheme . [HTML] [SW] -
-
request
’s
mode
is
"
same-origin
" -
Return a network error .
-
request
’s
mode
is
"
no-cors
" -
-
If request ’s redirect mode is not "
follow
", then return a network error . -
Set request ’s response tainting to "
opaque
". -
Let noCorsResponse be the result of performing a scheme fetch using request .
-
If noCorsResponse is a filtered response or the CORB check with request and noCorsResponse returns allowed , then return noCorsResponse .
-
Set corbSanitizedResponse to a new response whose status is noCorsResponse ’s status , HTTPS state is noCorsResponse ’s HTTPS state , and CSP list is noCorsResponse ’s CSP list .
This is only an effective defense against side channel attacks if noCorsResponse is kept isolated from the process that initiated the request.
-
Return corbSanitizedResponse .
-
- request ’s current url ’s scheme is not an HTTP(S) scheme
-
Return a network error .
-
request
’s
use-CORS-preflight
flag
is
set
- request ’s unsafe-request flag is set and either request ’s method is not a CORS-safelisted method or a header in request ’s header list is not a CORS-safelisted request-header
-
-
Set request ’s response tainting to "
cors
". -
Let corsWithPreflightResponse be the result of performing an HTTP fetch using request with CORS flag and CORS-preflight flag set.
-
If corsWithPreflightResponse is a network error , then clear cache entries using request .
-
Return corsWithPreflightResponse .
-
- Otherwise
-
-
Set request ’s response tainting to "
cors
". -
Return the result of performing an HTTP fetch using request with CORS flag set.
-
-
request
’s
current
url
’s
origin
is
same
origin
with
request
’s
origin
and
CORS
flag
is
unset
-
If the recursive flag is set, return response .
-
If response is not a network error and response is not a filtered response , then:
-
If request ’s response tainting is "
cors
", then:-
Let headerNames be the result of extracting header list values given `
Access-Control-Expose-Headers
` and response ’s header list . -
If request ’s credentials mode is not "
include
" and headerNames contains `*
`, then set response ’s CORS-exposed header-name list to all unique header names in response ’s header list . -
Otherwise, if headerNames is not null or failure, then set response ’s CORS-exposed header-name list to headerNames .
One of the headerNames can still be `
*
` at this point, but will only match a header whose name is `*
`.
-
-
Set response to the following filtered response with response as its internal response , depending on request ’s response tainting :
-
"
basic
" - basic filtered response
-
"
cors
" - CORS filtered response
-
"
opaque
" - opaque filtered response
-
"
-
-
Let internalResponse be response , if response is a network error , and response ’s internal response otherwise.
-
If internalResponse ’s url list is empty, then set it to a copy of request ’s url list .
A response ’s url list will typically be empty at this point, unless it came from a service worker, in which case it will only be empty if it was created through
new Response()
. -
If response is not a network error and any of the following algorithms returns blocked , then set response and internalResponse to a network error :
-
If response is not a network error and either request ’s method is `
HEAD
` or `CONNECT
`, or internalResponse ’s status is a null body status , set internalResponse ’s body to null and disregard any enqueuing toward it (if any).This standardizes the error handling for servers that violate HTTP.
-
If response is not a network error and request ’s integrity metadata is not the empty string, then:
-
If response ’s body ’s stream has not errored , and response does not match request ’s integrity metadata , set response and internalResponse to a network error . [SRI]
This operates on response as this algorithm is not supposed to observe internalResponse . That would allow an attacker to use hashes as an oracle.
-
If request ’s synchronous flag is set, wait for internalResponse ’s body , and then return response .
This terminates fetch .
-
If request ’s current url ’s scheme is an HTTP(S) scheme , then:
-
If request ’s body is done , queue a fetch-request-done task for request .
-
Otherwise, in parallel , wait for request ’s body , and then queue a fetch-request-done task for request .
-
-
Queue a fetch task on request to process response for response .
-
Queue a fetch task on request to process response end-of-body for response .
-
Wait for either internalResponse ’s trailer , if any, or for the ongoing fetch to terminate . See section 4.1.2 of [HTTP] .
-
If the ongoing fetch is terminated , then set internalResponse ’s trailer failed flag .
-
Set request ’s done flag .
-
Queue a fetch task on request to process response done for response .
4.2. Scheme fetch
To perform a scheme fetch using request , switch on request ’s current url ’s scheme , and run the associated steps:
-
"
about
" -
If request ’s current url ’s cannot-be-a-base-URL flag is set and path contains a single string "
blank
", then return a new response whose status message is `OK
`, header list consist of a single header whose name is `Content-Type
` and value is `text/html;charset=utf-8
`, body is the empty byte sequence, and HTTPS state is request ’s client ’s HTTPS state if request ’s client is non-null.Otherwise, return a network error .
URLs such as "
about:config
" are handled during navigation and result in a network error in the context of fetching . -
"
blob
" -
-
Run these steps, but abort when the ongoing fetch is terminated :
-
Let blob be request ’s current url ’s object .
-
If request ’s method is not `
GET
` or blob is not aBlob
object, then return a network error . [FILEAPI]The `
GET
` method restriction serves no useful purpose other than being interoperable. -
Let response be a new response whose status message is `
OK
`. -
Append `
Content-Length
`/ blob ’ssize
attribute value to response ’s header list . -
Append `
Content-Type
`/ blob ’stype
attribute value to response ’s header list . -
Set response ’s HTTPS state to request ’s client ’s HTTPS state if request ’s client is non-null.
-
Set response ’s body to the result of performing the read operation on blob .
-
Return response .
-
-
If aborted , then:
-
Let aborted be the termination’s aborted flag.
-
If aborted is set, then return an aborted network error .
-
Return a network error .
-
-
-
"
data
" -
-
Let dataURLStruct be the result of running the
data:
URL processor on request ’s current url . -
If dataURLStruct is failure, then return a network error .
-
Return a response whose status message is `
OK
`, header list consist of a single header whose name is `Content-Type
` and value is dataURLStruct ’s MIME type , serialized , body is dataURLStruct ’s body , and HTTPS state is request ’s client ’s HTTPS state if request ’s client is non-null.
-
-
"
file
"- "
ftp
" - "
-
For now, unfortunate as it is,
file
andftp
URLs are left as an exercise for the reader.When in doubt, return a network error .
-
"
filesystem
" -
If request ’s sandboxed-storage-area-URLs flag is set, return a network error .
Otherwise, … this scheme still needs to be defined.
- HTTP(S) scheme
-
Return the result of performing an HTTP fetch using request .
- Otherwise
-
Return a network error .
4.3. HTTP fetch
To perform an HTTP fetch using request with an optional CORS flag and CORS-preflight flag , run these steps:
CORS flag is still a bookkeeping detail. As is CORS-preflight flag ; it indicates a CORS-preflight request is needed.
-
Let response be null.
-
Let actualResponse be null.
-
If request ’s service-workers mode is "
all
", then:-
Set response to the result of invoking handle fetch for request . [HTML] [SW]
-
If response is not null, then:
-
Transmit body for request .
-
Set actualResponse to response , if response is not a filtered response , and to response ’s internal response otherwise.
-
If one of the following conditions is true, then return a network error :
-
response
’s
type
is
"
error
". -
request
’s
mode
is
"
same-origin
" and response ’s type is "cors
". -
request
’s
mode
is
not
"
no-cors
" and response ’s type is "opaque
". -
request
’s
redirect
mode
is
not
"
manual
" and response ’s type is "opaqueredirect
". -
request
’s
redirect
mode
is
not
"
follow
" and response ’s url list has more than one item.
-
response
’s
type
is
"
-
-
-
If response is null, then:
-
If the CORS-preflight flag is set and one of these conditions is true:
- There is no method cache match for request ’s method using request , and either request ’s method is a not a CORS-safelisted method or request ’s use-CORS-preflight flag is set.
- There is at least one header in request ’s header list for whose name there is no header-name cache match using request and which is not a CORS-safelisted request-header .
Then:
-
Let preflightResponse be the result of performing a CORS-preflight fetch using request .
-
If preflightResponse is a network error , then return preflightResponse .
This step checks the CORS-preflight cache and if there is no suitable entry it performs a CORS-preflight fetch which, if successful, populates the cache. The purpose of the CORS-preflight fetch is to ensure the fetched resource is familiar with the CORS protocol . The cache is there to minimize the number of CORS-preflight fetches .
-
If request ’s redirect mode is "
follow
", then set request ’s service-workers mode to "none
".Redirects coming from the network (as opposed to from a service worker) are not to be exposed to a service worker.
-
Set response and actualResponse to the result of performing an HTTP-network-or-cache fetch using request with CORS flag if set.
-
If CORS flag is set and a CORS check for request and response returns failure, then return a network error .
As the CORS check is not to be applied to responses whose status is
304
or407
, or responses from a service worker for that matter, it is applied here.
-
-
If actualResponse ’s status is a redirect status , then:
-
If actualResponse ’s status is not
303
, request ’s body is not null, and the connection uses HTTP/2, then user agents may, and are even encouraged to, transmit anRST_STREAM
frame.303
is excluded as certain communities ascribe special status to it. -
Let location be the result of extracting header list values given `
Location
` and actualResponse ’s header list . -
If location is a value , then set location to the result of parsing location with actualResponse ’s url .
-
Set actualResponse ’s location URL to location .
-
Switch on request ’s redirect mode :
-
"
error
" -
Set response to a network error .
-
"
manual
" -
Set response to an opaque-redirect filtered response whose internal response is actualResponse .
-
"
follow
" -
Set response to the result of performing HTTP-redirect fetch using request and response with CORS flag if set.
-
"
-
-
Return response . Typically actualResponse ’s body ’s stream is still being enqueued to after returning.
4.4. HTTP-redirect fetch
This algorithm is used by HTML’s navigate algorithm in addition to HTTP fetch above. [HTML]
To perform an HTTP-redirect fetch using request and response , with an optional CORS flag , run these steps:
-
Let actualResponse be response , if response is not a filtered response , and response ’s internal response otherwise.
-
If actualResponse ’s location URL is null, then return response .
-
If actualResponse ’s location URL is failure, then return a network error .
-
If actualResponse ’s location URL ’s scheme is not an HTTP(S) scheme , then return a network error .
-
If request ’s redirect count is twenty, return a network error .
-
Increase request ’s redirect count by one.
-
If request ’s mode is "
cors
", actualResponse ’s location URL includes credentials , and either request ’s tainted origin flag is set or request ’s origin is not same origin with actualResponse ’s location URL ’s origin , then return a network error . -
If CORS flag is set and actualResponse ’s location URL includes credentials , then return a network error .
This catches a cross-origin resource redirecting to a same-origin URL.
-
If actualResponse ’s status is not
303
, request ’s body is non-null, and request ’s body ’s source is null, then return a network error . -
If actualResponse ’s location URL ’s origin is not same origin with request ’s current url ’s origin and request ’s origin is not same origin with request ’s current url ’s origin , then set request ’s tainted origin flag .
-
If either actualResponse ’s status is
301
or302
and request ’s method is `POST
`, or actualResponse ’s status is303
, set request ’s method to `GET
` and request ’s body to null. -
If request ’s body is non-null, then set request ’s body to the first part of extracting request ’s body ’s source .
request ’s body ’s source ’s nullity has already been checked. The extracting operation cannot throw as it was called for the same source before.
-
Append actualResponse ’s location URL to request ’s url list .
-
Invoke set request ’s referrer policy on redirect on request and actualResponse . [REFERRER]
-
Return the result of performing a main fetch using request with
-
CORS flag if set and
-
recursive flag set if request ’s redirect mode is not "
manual
".It can only be "
manual
" when invoked directly from HTML’s navigate algorithm.
This has to invoke main fetch to get response tainting correct.
-
4.5. HTTP-network-or-cache fetch
To perform an HTTP-network-or-cache fetch using request with an optional CORS flag and authentication-fetch flag , run these steps:
CORS flag is still a bookkeeping detail. As is authentication-fetch flag .
Some implementations might support caching of partial content, as per HTTP Range Requests . [HTTP-RANGE] However, this is not widely supported by browser caches.
-
Let httpRequest be null.
-
Run these steps, but abort when the ongoing fetch is terminated :
-
If request ’s window is "
no-window
" and request ’s redirect mode is "error
", then set httpRequest to request . -
Otherwise:
-
Set httpRequest to a copy of request except for its body .
-
Let body be request ’s body .
-
Set httpRequest ’s body to body .
-
If body is non-null, then set request ’s body to a new body whose stream is null and whose source is body ’s source .
request is copied as httpRequest here as we need to be able to add headers to httpRequest and read its body without affecting request . Namely, request can be reused with redirects, authentication, and proxy authentication. We copy rather than clone in order to reduce memory consumption. In case request ’s body ’s source is null, redirects and authentication will end up failing the fetch.
-
-
Let credentials flag be set if one of
-
request
’s
credentials
mode
is
"
include
" -
request
’s
credentials
mode
is
"
same-origin
" and request ’s response tainting is "basic
"
is true, and unset otherwise.
-
request
’s
credentials
mode
is
"
-
Let contentLengthValue be null.
-
If httpRequest ’s body is null and httpRequest ’s method is `
POST
` or `PUT
`, then set contentLengthValue to `0
`. -
If httpRequest ’s body is non-null and httpRequest ’s body ’s source is non-null, then set contentLengthValue to httpRequest ’s body ’s total bytes , UTF-8 encoded .
-
If contentLengthValue is non-null, append `
Content-Length
`/ contentLengthValue to httpRequest ’s header list . -
If contentLengthValue is non-null and httpRequest ’s keepalive flag is set, then:
-
Let inflightKeepaliveBytes be zero.
-
Let group be httpRequest ’s client ’s fetch group .
-
Let inflightRecords be the set of fetch records in group whose request has its keepalive flag set and done flag unset.
-
For each fetchRecord in inflightRecords :
-
Let inflightRequest be fetchRecord ’s request .
-
Increment inflightKeepaliveBytes by inflightRequest ’s body ’s total bytes .
-
-
If the sum of contentLengthValue and inflightKeepaliveBytes is greater than 64 kibibytes, then return a network error .
The above limit ensures that requests that are allowed to outlive the environment settings object and contain a body, have a bounded size and are not allowed to stay alive indefinitely.
-
-
If httpRequest ’s referrer is a URL , then append `
Referer
`/ httpRequest ’s referrer , serialized andUTF-8isomorphic encoded , to httpRequest ’s header list . -
If the CORS flag is set, httpRequest ’s method is neither `
GET
` nor `HEAD
`, or httpRequest ’s mode is "websocket
", then append `Origin
`/the result of serializing a request origin with httpRequest , to httpRequest ’s header list . -
If httpRequest ’s header list does not contain `
User-Agent
`, then user agents should append `User-Agent
`/ default `User-Agent
` value to httpRequest ’s header list . -
If httpRequest ’s cache mode is "
default
" and httpRequest ’s header list contains `If-Modified-Since
`, `If-None-Match
`, `If-Unmodified-Since
`, `If-Match
`, or `If-Range
`, then set httpRequest ’s cache mode to "no-store
". -
If httpRequest ’s cache mode is "
no-cache
" and httpRequest ’s header list does not contain `Cache-Control
`, then append `Cache-Control
`/`max-age=0
` to httpRequest ’s header list . -
If httpRequest ’s cache mode is "
no-store
" or "reload
", then:-
If httpRequest ’s header list does not contain `
Pragma
`, then append `Pragma
`/`no-cache
` to httpRequest ’s header list . -
If httpRequest ’s header list does not contain `
Cache-Control
`, then append `Cache-Control
`/`no-cache
` to httpRequest ’s header list .
-
-
Modify httpRequest ’s header list per HTTP.
It would be great if we could make this more normative somehow. At this point headers such as `
Accept-Encoding
`, `Connection
`, `DNT
`, and `Host
`, are to be appended if necessary.`
Accept
`, `Accept-Charset
`, and `Accept-Language
` must not be included at this point.`
Accept
` and `Accept-Language
` are already included (unlessfetch()
is used, which does not include the latter by default), and `Accept-Charset
` is a waste of bytes. See HTTP header layer division for more details. -
If credentials flag is set, then:
-
If the user agent is not configured to block cookies for httpRequest (see section 7 of [COOKIES] ), then:
-
Let cookies be the result of running the "cookie-string" algorithm (see section 5.4 of [COOKIES] ) with the user agent’s cookie store and httpRequest ’s current url .
-
If
cookies
is
not
the
empty
string,
append
`
Cookie
`/ cookies to httpRequest ’s header list .
-
-
If httpRequest ’s header list does not contain `
Authorization
`, then:-
Let authorizationValue be null.
-
If there’s an authentication entry for httpRequest and either httpRequest ’s use-URL-credentials flag is unset or httpRequest ’s current url does not include credentials , then set authorizationValue to authentication entry .
-
Otherwise, if httpRequest ’s current url does include credentials and authentication-fetch flag is set, set authorizationValue to httpRequest ’s current url , converted to an `
Authorization
` value . -
If authorizationValue is non-null, then append `
Authorization
`/ authorizationValue to httpRequest ’s header list .
-
-
-
If there’s a proxy-authentication entry , use it as appropriate.
This intentionally does not depend on httpRequest ’s credentials mode .
-
Let response and storedResponse be null.
-
Let the revalidatingFlag be unset.
-
If httpRequest ’s cache mode is neither "
no-store
" nor "reload
", then:-
Set storedResponse to the result of selecting a response from the HTTP cache, possibly needing validation, as per the " Constructing Responses from Caches " chapter of HTTP Caching [HTTP-CACHING] , if any.
As mandated by HTTP, this still takes the `
Vary
` header into account. -
If storedResponse is non-null, then:
-
If storedResponse requires validation (i.e., it is not fresh), then set the revalidatingFlag .
-
If the revalidatingFlag is set and httpRequest ’s cache mode is neither "
force-cache
" nor "only-if-cached
", then:-
If storedResponse ’s header list contains `
ETag
`, then append `If-None-Match
` with its value to httpRequest ’s header list . -
If storedResponse ’s header list contains `
Last-Modified
`, then append `If-Modified-Since
` with its value to httpRequest ’s header list .
See also the " Sending a Validation Request " chapter of HTTP Caching [HTTP-CACHING] .
-
-
Otherwise, set response to storedResponse and set response ’s cache state to "
local
".
-
-
-
-
If aborted , then:
-
Let aborted be the termination’s aborted flag.
-
If aborted is set, then return an aborted network error .
-
Return a network error .
-
-
If response is null, then:
-
If httpRequest ’s cache mode is "
only-if-cached
", then return a network error . -
Set forwardResponse to the result of making an HTTP-network fetch using httpRequest with credentials flag if set.
-
If httpRequest ’s method is unsafe and forwardResponse ’s status is in the range
200
to399
, inclusive, invalidate appropriate stored responses in the HTTP cache, as per the " Invalidation " chapter of HTTP Caching , and set storedResponse to null. [HTTP-CACHING] -
If the revalidatingFlag is set and forwardResponse ’s status is
304
, then:-
Update storedResponse ’s header list using forwardResponse ’s header list , as per the " Freshening Stored Responses upon Validation " chapter of HTTP Caching . [HTTP-CACHING]
This updates the stored response in cache as well.
-
Set response to storedResponse .
-
-
If response is null, then:
-
Set response to forwardResponse .
-
Store httpRequest and forwardResponse in the HTTP cache, as per the " Storing Responses in Caches " chapter of HTTP Caching . [HTTP-CACHING]
If forwardResponse is a network error , this effectively caches the network error, which is sometimes known as "negative caching".
-
-
-
If response ’s status is
401
, CORS flag is unset, credentials flag is set, and request ’s window is an environment settings object , then:-
Needs testing: multiple `
WWW-Authenticate
` headers, missing, parsing issues. -
If request ’s body is non-null, then:
-
If request ’s body ’s source is null, then return a network error .
-
Set request ’s body to the first part of extracting request ’s body ’s source .
The extracting operation cannot throw as it was called for the same source before.
-
-
If request ’s use-URL-credentials flag is unset or authentication-fetch flag is set, then:
-
If the ongoing fetch is terminated , then:
-
Let aborted be the termination’s aborted flag.
-
If aborted is set, then return an aborted network error .
-
Return a network error .
-
-
Let username and password be the result of prompting the end user for a username and password, respectively, in request ’s window .
-
Set the username given request ’s current url and username .
-
Set the password given request ’s current url and password .
-
-
Set response to the result of performing an HTTP-network-or-cache fetch using request with authentication-fetch flag set.
-
-
If response ’s status is
407
, then:-
If request ’s window is "
no-window
", then return a network error . -
Needs testing: multiple `
Proxy-Authenticate
` headers, missing, parsing issues. -
If the ongoing fetch is terminated , then:
-
Let aborted be the termination’s aborted flag.
-
If aborted is set, then return an aborted network error .
-
Return a network error .
-
-
Prompt the end user as appropriate in request ’s window and store the result as a proxy-authentication entry . [HTTP-AUTH]
Remaining details surrounding proxy authentication are defined by HTTP.
-
Set response to the result of performing an HTTP-network-or-cache fetch using request with CORS flag if set.
-
-
If authentication-fetch flag is set, then create an authentication entry for request and the given realm.
-
Return response . Typically response ’s body ’s stream is still being enqueued to after returning.
4.6. HTTP-network fetch
To perform an HTTP-network fetch using request with an optional credentials flag , run these steps:
-
Let credentials be true if credentials flag is set, and false otherwise.
-
Let response be null.
-
Switch on request ’s mode :
-
"
websocket
" -
Let connection be the result of obtaining a WebSocket connection , given request ’s current url .
- Otherwise
-
Let connection be the result of obtaining a connection , given request ’s current url ’s origin and credentials .
-
"
-
Run these steps, but abort when the ongoing fetch is terminated :
-
If connection is failure, return a network error .
-
If connection is not an HTTP/2 connection, request ’s body is non-null, and request ’s body ’s source is null, then append `
Transfer-Encoding
`/`chunked
` to request ’s header list . -
Set response to the result of making an HTTP request over connection using request with the following caveats:
-
Follow the relevant requirements from HTTP. [HTTP] [HTTP-SEMANTICS] [HTTP-COND] [HTTP-CACHING] [HTTP-AUTH]
-
Wait until all the headers are transmitted.
-
Any responses whose status is in the range
100
to199
, inclusive, and is not101
, are to be ignored.These kind of responses are eventually followed by a "final" response .
The exact layering between Fetch and HTTP still needs to be sorted through and therefore response represents both a response and an HTTP response here.
If request ’s header list contains `
Transfer-Encoding
`/`chunked
` and response is transferred via HTTP/1.0 or older, then return a network error .If the HTTP request results in a TLS client certificate dialog, then:
-
If request ’s window is an environment settings object , make the dialog available in request ’s window .
-
Otherwise, return a network error .
If response was retrieved over HTTPS, set its HTTPS state to either "
deprecated
" or "modern
". [TLS]The exact determination here is up to user agents for the time being. User agents are strongly encouraged to only succeed HTTPS connections with strong security properties and return network errors otherwise. Using the "
deprecated
" state value ought to be a temporary and last resort kind of option.Transmit body for request .
-
-
-
If aborted , then:
-
Let aborted be the termination’s aborted flag.
-
If connection uses HTTP/2, then transmit an
RST_STREAM
frame. -
If aborted is set, then return an aborted network error .
-
Return a network error .
-
-
Let strategy be an object. The user agent may choose any object.
strategy is used to control the queuing strategy of stream constructed below.
-
Let pull be an action that resumes the ongoing fetch if it is suspended .
-
Let cancel be an action that terminates the ongoing fetch with the aborted flag set.
-
Let stream be the result of constructing a
ReadableStream
object with strategy , pull and cancel .This construction operation will not throw an exception.
-
Run these steps, but abort when the ongoing fetch is terminated :
-
If response has a payload body length, then set response ’s body ’s total bytes to that payload body length.
-
Delete `
Content-Encoding
` from response ’s header list if one of the following conditions is true:-
Extracting header list values given `
Content-Encoding
` and response ’s header list returns `gzip
`, and extracting header list values given `Content-Type
` and response ’s header list returns `application/gzip
`, `application/x-gunzip
`, or `application/x-gzip
`. -
Extracting header list values given `
Content-Encoding
` and response ’s header list returns `compress
`, and extracting header list values given `Content-Type
` and response ’s header list returns `application/compress
` or `application/x-compress
.
This deals with broken Apache configurations. Ideally HTTP would define this.
Gecko bug 1030660 looks into whether this quirk can be removed.
-
-
If response is not a network error and request ’s cache mode is not "
no-store
", update response in the HTTP cache for request . -
If credentials flag is set and the user agent is not configured to block cookies for request (see section 7 of [COOKIES] ), then run the "set-cookie-string" parsing algorithm (see section 5.2 of [COOKIES] ) on the value of each header whose name is a byte-case-insensitive match for `
Set-Cookie
` in response ’s header list , if any, and request ’s current url .This is a fingerprinting vector.
-
If aborted , then:
-
Let aborted be the termination’s aborted flag.
-
If aborted is set, then set response ’s aborted flag .
-
Return response .
-
-
Run these steps in parallel :
-
Run these steps, but abort when the ongoing fetch is terminated :
-
While true:
-
If one or more bytes have been transmitted from response ’s message body, then:
-
Let bytes be the transmitted bytes.
-
Increase response ’s body ’s transmitted bytes with bytes ’ length.
-
Let codings be the result of extracting header list values given `
Content-Encoding
` and response ’s header list . -
Set bytes to the result of handling content codings given codings and bytes .
This makes the `
Content-Length
` header unreliable to the extent that it was reliable to begin with. -
If bytes is failure, then terminate the ongoing fetch.
-
Enqueue a
Uint8Array
object wrapping anArrayBuffer
containing bytes to stream . If that threw an exception, terminate the ongoing fetch, and error stream with that exception. -
If stream doesn’t need more data and request ’s synchronous flag is unset, ask the user agent to suspend the ongoing fetch.
-
-
Otherwise, if the bytes transmission for response ’s message body is done normally and stream is readable , then close stream and abort these in-parallel steps.
-
-
-
If aborted , then:
-
Let aborted be the termination’s aborted flag.
-
If aborted is set, then:
-
Set response ’s aborted flag .
-
If stream is readable , error stream with an "
AbortError
"DOMException
.
-
-
Otherwise, if stream is readable , error stream with a
TypeError
. -
If connection uses HTTP/2, then transmit an
RST_STREAM
frame. -
Otherwise, the user agent should close connection unless it would be bad for performance to do so.
For instance, the user agent could keep the connection open if it knows there’s only a few bytes of transfer remaining on a reusable connection. In this case it could be worse to close the connection and go through the handshake process again for the next fetch.
-
These are run in parallel as at this point it is unclear whether response ’s body is relevant ( response might be a redirect).
-
-
Return response . Typically response ’s body ’s stream is still being enqueued to after returning.
4.7. CORS-preflight fetch
This is effectively the user agent implementation of the check to see if the CORS protocol is understood. The so-called CORS-preflight request . If successful it populates the CORS-preflight cache to minimize the number of these fetches .
To perform a CORS-preflight fetch using request , run these steps:
-
Let preflight be a new request whose method is `
OPTIONS
`, url is request ’s current url , initiator is request ’s initiator , destination is request ’s destination , origin is request ’s origin , referrer is request ’s referrer , referrer policy is request ’s referrer policy , and tainted origin flag is request ’s tainted origin flag .The service-workers mode of preflight does not matter as this algorithm uses HTTP-network-or-cache fetch rather than HTTP fetch .
-
Set `
Access-Control-Request-Method
` to request ’s method in preflight ’s header list . -
Let headers be the names of request ’s header list ’s headers , excluding CORS-safelisted request-headers and duplicates, sorted lexicographically, and byte-lowercased .
-
If headers is not empty , then:
-
Let value be the items in headers separated from each other by `
,
`. -
Set `
Access-Control-Request-Headers
` to value in preflight ’s header list .
This intentionally does not use combine , as 0x20 following 0x2C is not the way this was implemented, for better or worse.
-
-
Let response be the result of performing an HTTP-network-or-cache fetch using preflight .
-
If a CORS check for request and response returns success and response ’s status is an ok status , then:
The CORS check is done on request rather than preflight to ensure the correct credentials mode is used.
-
Let methods be the result of extracting header list values given `
Access-Control-Allow-Methods
` and response ’s header list . -
Let headerNames be the result of extracting header list values given `
Access-Control-Allow-Headers
` and response ’s header list . -
If either methods or headerNames is failure, return a network error .
-
If methods is null and request ’s use-CORS-preflight flag is set, then set methods to a new list containing request ’s method .
This ensures that a CORS-preflight fetch that happened due to request ’s use-CORS-preflight flag being set is cached .
-
If request ’s method is not in methods , request ’s method is not a CORS-safelisted method , and request ’s credentials mode is "
include
" or methods does not contain `*
`, then return a network error . -
If one of request ’s header list ’s names is a CORS non-wildcard request-header name and is not a byte-case-insensitive match for an item in headerNames , then return a network error .
-
For each header in request ’s header list : if header is not a CORS-safelisted request-header , header ’s name is not a byte-case-insensitive match for an item in headerNames , and request ’s credentials mode is "
include
" or headerNames does not contain `*
`, then return a network error . -
Let max-age be the result of extracting header list values given `
Access-Control-Max-Age
` and response ’s header list . -
If max-age is failure or null, then set max-age to zero.
-
If max-age is greater than an imposed limit on max-age , then set max-age to the imposed limit.
-
If the user agent does not provide for a cache , then return response .
-
For each method in methods for which there is a method cache match using request , set matching entry’s max-age to max-age .
-
For each method in methods for which there is no method cache match using request , create a new entry with request , max-age , method , and null.
-
For each headerName in headerNames for which there is a header-name cache match using request , set matching entry’s max-age to max-age .
-
For each headerName in headerNames for which there is no header-name cache match using request , create a new entry with request , max-age , null, and headerName .
-
Return response .
-
-
Otherwise, return a network error .
4.8. CORS-preflight cache
A CORS-preflight cache consists of a collection of entries where each entry has these fields:
- serialized origin (a byte sequence )
- url (a URL )
- max-age (a number of seconds)
- credentials (a boolean)
-
method
(null,
`
*
`, or a method ) -
header
name
(null,
`
*
`, or a header name )
Entries must be removed after the seconds specified in the max-age field have passed since storing the entry. Entries may be removed before that moment arrives.
To create a new entry in the CORS-preflight cache , given request , max-age , method , and headerName , do so as follows:
- serialized origin
- The result of serializing a request origin with request
- url
- request ’s current url
- max-age
- max-age
- credentials
-
True
if
request
’s
credentials
mode
is
"
include
", and false otherwise - method
- method
- header name
- headerName
To clear cache entries , given a request , remove any entries in the CORS-preflight cache whose serialized origin is the result of serializing a request origin with request and whose url is request ’s current url .
There is a cache match for request if serialized origin is the result of serializing a request origin with request , url is request ’s current url , and one of
- credentials is true
-
credentials
is
false
and
request
’s
credentials
mode
is
not
"
include
".
is true.
There
is
a
method
cache
match
for
method
using
request
when
there
is
an
entry
in
CORS-preflight
cache
for
which
there
is
a
cache
match
for
request
and
its
method
is
method
or
`
*
`.
There is a header-name cache match for headerName using request when there is an entry in CORS-preflight cache for which there is a cache match for request and one of
- header name is a byte-case-insensitive match for headerName
-
header
name
is
`
*
` and headerName is not a CORS non-wildcard request-header name
is true.
4.9. CORS check
To perform a CORS check for a request and response , run these steps:
-
Let origin be the result of extracting header list values given `
Access-Control-Allow-Origin
` and response ’s header list .The above will fail for network errors, as they have no headers.
-
If origin is null or failure, return failure.
Null is not `
null
`. -
If request ’s credentials mode is not "
include
" and origin is `*
`, return success. -
If the result of serializing a request origin with request is not origin , then return failure.
-
If request ’s credentials mode is not "
include
", return success. -
Let credentials be the result of extracting header list values given `
Access-Control-Allow-Credentials
` and response ’s header list . -
If credentials is `
true
`, return success. -
Return failure.
5. Fetch API
The
fetch()
method
is
relatively
low-level
API
for
fetching
resources.
It
covers
slightly
more
ground
than
XMLHttpRequest
,
although
it
is
currently
lacking
when
it
comes
to
request
progression
(not
response
progression).
The
fetch()
method
makes
it
quite
straightforward
to
fetch
a
resource
and
extract
its
contents
as
a
Blob
:
fetch("/music/pk/altes-kamuffel.flac") .then(res => res.blob()).then(playBlob)
If you just care to log a particular response header:
fetch("/", {method:"HEAD"}) .then(res => log(res.headers.get("strict-transport-security")))
If you want to check a particular response header and then process the response of a cross-origin resources:
fetch("https://pk.example/berlin-calling.json", {mode:"cors"}) .then(res => { if(res.headers.get("content-type") && res.headers.get("content-type").toLowerCase().indexOf("application/json") >= 0) { return res.json() } else { throw new TypeError() } }).then(processJSON)
If you want to work with URL query parameters:
var url = new URL("https://geo.example.org/api"), params = {lat:35.696233, long:139.570431} Object.keys(params).forEach(key => url.searchParams.append(key, params[key])) fetch(url).then(/* … */)
If you want to receive the body data progressively:
function consume(reader) { var total = 0 return pump() function pump() { return reader.read().then(({done, value}) => { if (done) { return } total += value.byteLength log(`received ${value.byteLength} bytes (${total} bytes in total)`) return pump() }) } } fetch("/music/pk/altes-kamuffel.flac") .then(res => consume(res.body.getReader())) .then(() => log("consumed the entire body without keeping the whole thing in memory!")) .catch(e => log("something went wrong: " + e))
5.1. Headers class
typedef (sequence<sequence<ByteString>> or record<ByteString, ByteString>)HeadersInit
; [Constructor(optional HeadersInitinit
), Exposed=(Window,Worker)] interfaceHeaders
{ void append(ByteStringname
, ByteStringvalue
); void delete(ByteStringname
); ByteString? get(ByteStringname
); boolean has(ByteStringname
); void set(ByteStringname
, ByteStringvalue
); iterable<ByteString, ByteString>; };
Constructing
a
Headers
object
from
scratch
is
fairly
straightforward.
You
could
pass
in
a
JavaScript
object
representing
a
header
hash
map,
or
an
array
of
ordered
pairs:
var meta = { "Content-Type": "text/xml", "Breaking-Bad": "<3" } new Headers(meta) // The above is equivalent to var meta = [ [ "Content-Type", "text/xml" ], [ "Breaking-Bad", "<3" ] ] new Headers(meta)
A
Headers
object
has
an
associated
header
list
(a
header
list
),
which
is
initially
empty.
This
can
be
a
pointer
to
the
header
list
of
something
else,
e.g.,
of
a
request
as
demonstrated
by
Request
objects.
A
Headers
object
also
has
an
associated
guard
,
which
is
"
immutable
",
"
request
",
"
request-no-cors
",
"
response
"
or
"
none
".
"
immutable
"
exists
for
service
workers.
[SW]
To
append
a
name
/
value
(
name
/
value
)
pair
to
a
Headers
object
(
headers
),
run
these
steps:
-
Normalize value .
-
If name is not a name or value is not a value , then throw a
TypeError
. -
Otherwise, if guard is "
request
" and name is a forbidden header name , return. -
Otherwise, if guard is "
request-no-cors
" and name / value is not a CORS-safelisted request-header , return. -
Otherwise, if guard is "
response
" and name is a forbidden response-header name , return. -
Append name / value to header list .
To
fill
a
Headers
object
(
headers
)
with
a
given
object
(
object
),
run
these
steps:
-
Otherwise, object is a record , then for each key → value in object , append key / value to headers .
The
Headers(
init
)
constructor,
when
invoked,
must
run
these
steps:
-
Let headers be a new
Headers
object whose guard is "none
". -
If init is given, fill headers with init .
-
Return headers .
The
append(
name
,
value
)
method,
when
invoked,
must
append
name
/
value
to
context
object
.
The
delete(
name
)
method,
when
invoked,
must
run
these
steps:
-
Otherwise, if guard is "
request
" and name is a forbidden header name , return. -
Otherwise, if guard is "
request-no-cors
" and name /`invalid
` is not a CORS-safelisted request-header , then return.`
invalid
` is used becausedelete()
is not passed a value as argument. -
Otherwise, if guard is "
response
" and name is a forbidden response-header name , return. -
Delete name from header list .
The
get(
name
)
method,
when
invoked,
must
run
these
steps:
-
If header list does not contain name , then return null.
-
Return the combined value given name and header list .
The
has(
name
)
method,
when
invoked,
must
run
these
steps:
-
Return true if header list contains name , and false otherwise.
The
set(
name
,
value
)
method,
when
invoked,
must
run
these
steps:
-
Normalize value .
-
If name is not a name or value is not a value , then throw a
TypeError
. -
Otherwise, if guard is "
request
" and name is a forbidden header name , return. -
Otherwise, if guard is "
request-no-cors
" and name / value is not a CORS-safelisted request-header , return. -
Otherwise, if guard is "
response
" and name is a forbidden response-header name , return. -
Set name / value in header list .
The value pairs to iterate over are the return value of running sort and combine with the header list .
5.2. Body mixin
typedef
(
Blob
or
BufferSource
or
FormData
or
URLSearchParams
or
ReadableStream
or
USVString
)
BodyInit
;
To
extract
a
body
and
a
`
Content-Type
`
value
from
object
,
with
an
optional
keepalive
flag
,
run
these
steps:
-
Let stream be the result of constructing a
ReadableStream
object. -
Let Content-Type be null.
-
Let action be null.
-
Let source be null.
-
Switch on object ’s type:
-
Blob
-
Set action to an action that reads object .
If object ’s
type
attribute is not the empty byte sequence, set Content-Type to its value.Set source to object .
-
BufferSource
-
Enqueue a
Uint8Array
object wrapping anArrayBuffer
containing a copy of the bytes held by object to stream and close stream . If that threw an exception, error stream with that exception.Set source to object .
-
FormData
-
Set action to an action that runs the
multipart/form-data
encoding algorithm , with object as form data set and with UTF-8 as the explicit character encoding.Set Content-Type to `
multipart/form-data; boundary=
`, followed by themultipart/form-data
boundary string generated by themultipart/form-data
encoding algorithm .Set source to object .
-
URLSearchParams
-
Set action to an action that runs the
application/x-www-form-urlencoded
serializer with object ’s list .Set Content-Type to `
application/x-www-form-urlencoded;charset=UTF-8
`.Set source to object .
-
USVString
-
Set action to an action that runs UTF-8 encode on object .
Set Content-Type to `
text/plain;charset=UTF-8
`.Set source to object .
-
ReadableStream
-
Set stream to object .
-
-
If keepalive flag is set and object ’s type is a
ReadableStream
object, then throw aTypeError
. -
If action is non-null, run action in parallel :
-
Whenever one or more bytes are available, let bytes be the bytes and enqueue a
Uint8Array
object wrapping anArrayBuffer
containing bytes to stream . If creating theArrayBuffer
threw an exception, error stream with that exception and cancel running action . -
When running action is done, close stream .
-
-
Let body be a body whose stream is stream and whose source is source .
-
Return body and Content-Type .
interface mixin Body
{
readonly attribute ReadableStream? body;
readonly attribute boolean bodyUsed;
[NewObject] Promise<ArrayBuffer> arrayBuffer();
[NewObject] Promise<Blob> blob();
[NewObject] Promise<FormData> formData();
[NewObject] Promise<any> json();
[NewObject] Promise<USVString> text();
};
Formats you would not want a network layer to be dependent upon, such as HTML, will likely not be exposed here. Rather, an HTML parser API might accept a stream in due course.
Objects
implementing
the
Body
mixin
gain
an
associated
body
(null
or
a
body
)
and
a
MIME
type
(initially
the
empty
byte
sequence).
An
object
implementing
the
Body
mixin
is
said
to
be
disturbed
if
body
is
non-null
and
its
stream
is
disturbed
.
An
object
implementing
the
Body
mixin
is
said
to
be
locked
if
body
is
non-null
and
its
stream
is
locked
.
The
body
attribute’s
getter
must
return
null
if
body
is
null
and
body
’s
stream
otherwise.
The
bodyUsed
attribute’s
getter
must
return
true
if
disturbed
,
and
false
otherwise.
Objects
implementing
the
Body
mixin
also
have
an
associated
package
data
algorithm,
given
bytes
,
a
type
and
a
mimeType
,
switches
on
type
,
and
runs
the
associated
steps:
- ArrayBuffer
-
Return a new
ArrayBuffer
whose contents are bytes .Allocating an
ArrayBuffer
can throw aRangeError
. - Blob
-
Return a
Blob
whose contents are bytes andtype
attribute is mimeType . - FormData
-
If mimeType (ignoring parameters) is `
multipart/form-data
`, then:-
Parse bytes , using the value of the `
boundary
` parameter from mimeType , per the rules set forth in Returning Values from Forms: multipart/form-data . [RFC7578]Each part whose `
Content-Disposition
` header contains a `filename
` parameter must be parsed into an entry whose value is aFile
object whose contents are the contents of the part. Thename
attribute of theFile
object must have the value of the `filename
` parameter of the part. Thetype
attribute of theFile
object must have the value of the `Content-Type
` header of the part if the part has such header, and `text/plain
` (the default defined by [RFC7578] section 4.4) otherwise.Each part whose `
Content-Disposition
` header does not contain a `filename
` parameter must be parsed into an entry whose value is the UTF-8 decoded content of the part. This is done regardless of the presence or the value of a `Content-Type
` header and regardless of the presence or the value of a `charset
` parameter.A part whose `
Content-Disposition
` header contains a `name
` parameter whose value is `_charset_
` is parsed like any other part. It does not change the encoding. -
If that fails for some reason, then throw a
TypeError
. -
Return a new
FormData
object, appending each entry , resulting from the parsing operation, to entries .
The above is a rough approximation of what is needed for `
multipart/form-data
`, a more detailed parsing specification is to be written. Volunteers welcome.Otherwise, if mimeType (ignoring parameters) is `
application/x-www-form-urlencoded
`, then:Otherwise, throw a
TypeError
. -
- JSON
-
Return the result of running parse JSON from bytes on bytes .
- text
-
Return the result of running UTF-8 decode on bytes .
Objects
implementing
the
Body
mixin
also
have
an
associated
consume
body
algorithm,
given
a
type
,
runs
these
steps:
-
If this object is disturbed or locked , return a new promise rejected with a
TypeError
. -
Let stream be body ’s stream if body is non-null, or an empty
ReadableStream
object otherwise. -
Let reader be the result of getting a reader from stream . If that threw an exception, return a new promise rejected with that exception.
-
Let promise be the result of reading all bytes from stream with reader .
-
Return the result of transforming promise by a fulfillment handler that returns the result of the package data algorithm with its first argument, type and this object’s MIME type .
The
arrayBuffer()
method,
when
invoked,
must
return
the
result
of
running
consume
body
with
ArrayBuffer
.
The
blob()
method,
when
invoked,
must
return
the
result
of
running
consume
body
with
Blob
.
The
formData()
method,
when
invoked,
must
return
the
result
of
running
consume
body
with
FormData
.
The
json()
method,
when
invoked,
must
return
the
result
of
running
consume
body
with
JSON
.
The
text()
method,
when
invoked,
must
return
the
result
of
running
consume
body
with
text
.
5.3. Request class
typedef (Request or USVString)RequestInfo
; [Constructor(RequestInfoinput
, optional RequestInitinit
), Exposed=(Window,Worker)] interfaceRequest
{ readonly attribute ByteString method; readonly attribute USVString url; [SameObject] readonly attribute Headers headers; readonly attribute RequestDestination destination; readonly attribute USVString referrer; readonly attribute ReferrerPolicy referrerPolicy; readonly attribute RequestMode mode; readonly attribute RequestCredentials credentials; readonly attribute RequestCache cache; readonly attribute RequestRedirect redirect; readonly attribute DOMString integrity; readonly attribute boolean keepalive; readonly attribute boolean isReloadNavigation; readonly attribute AbortSignal signal; [NewObject] Request clone(); }; Request includes Body; dictionaryRequestInit
{ ByteStringmethod
; HeadersInitheaders
; BodyInit?body
; USVStringreferrer
; ReferrerPolicyreferrerPolicy
; RequestModemode
; RequestCredentialscredentials
; RequestCachecache
; RequestRedirectredirect
; DOMStringintegrity
; booleankeepalive
; AbortSignal?signal
; anywindow
; // can only be set to null }; enumRequestDestination
{""
,"audio"
,"audioworklet"
,"document"
,"embed"
,"font"
,"image"
,"manifest"
,"object"
,"paintworklet"
,"report"
,"script"
,"sharedworker"
,"style"
,"track"
,"video"
,"worker"
,"xslt"
}; enumRequestMode
{"navigate"
,"same-origin"
,"no-cors"
,"cors"
}; enumRequestCredentials
{"omit"
,"same-origin"
,"include"
}; enumRequestCache
{"default"
,"no-store"
,"reload"
,"no-cache"
,"force-cache"
,"only-if-cached"
}; enumRequestRedirect
{"follow"
,"error"
,"manual"
};
"
serviceworker
"
is
omitted
from
RequestDestination
as
it
cannot
be
observed
from
JavaScript.
Implementations
will
still
need
to
support
it
as
a
destination
.
"
websocket
"
is
omitted
from
RequestMode
as
it
cannot
be
used
nor
observed
from
JavaScript.
A
Request
object
has
an
associated
request
(a
request
).
A
Request
object
also
has
an
associated
headers
(null
or
a
Headers
object),
initially
null.
A
Request
object
has
an
associated
signal
(an
AbortSignal
object),
initially
a
new
AbortSignal
object.
A
Request
object’s
body
is
its
request
’s
body
.
-
request = new Request ( input [, init ])
-
Returns a new request whose
url
property is input if input is a string, and input ’surl
if input is aRequest
object.The init argument is an object whose properties can be set as follows:
-
method
-
A
string
to
set
request
’s
method
. -
headers
-
A
Headers
object, an object literal, or an array of two-item arrays to set request ’sheaders
. -
body
-
A
BodyInit
object or null to set request ’s body . -
referrer
-
A
string
whose
value
is
a
same-origin
URL,
"
about:client
", or the empty string, to set request ’s referrer . -
referrerPolicy
-
A
referrer
policy
to
set
request
’s
referrerPolicy
. -
mode
-
A
string
to
indicate
whether
the
request
will
use
CORS,
or
will
be
restricted
to
same-origin
URLs.
Sets
request
’s
mode
. -
credentials
-
A
string
indicating
whether
credentials
will
be
sent
with
the
request
always,
never,
or
only
when
sent
to
a
same-origin
URL.
Sets
request
’s
credentials
. -
cache
-
A
string
indicating
how
the
request
will
interact
with
the
browser’s
cache
to
set
request
’s
cache
. -
redirect
-
A
string
indicating
whether
request
follows
redirects,
results
in
an
error
upon
encountering
a
redirect,
or
returns
the
redirect
(in
an
opaque
fashion).
Sets
request
’s
redirect
. -
integrity
-
A
cryptographic
hash
of
the
resource
to
be
fetched
by
request
.
Sets
request
’s
integrity
. -
keepalive
-
A
boolean
to
set
request
’s
keepalive
. -
signal
-
An
AbortSignal
to set request ’ssignal
. -
window
-
Can
only
be
null.
Used
to
disassociate
request
from
any
Window
.
-
-
request . method
-
Returns
request
’s
HTTP
method,
which
is
"
GET
" by default. -
request . url
- Returns the URL of request as a string.
-
request . headers
-
Returns
a
Headers
object consisting of the headers associated with request . Note that headers added in the network layer by the user agent will not be accounted for in this object, e.g., the "Host
" header. -
request . destination
-
Returns
the
kind
of
resource
requested
by
request
,
e.g.,
"
document
" or "script
". -
request . referrer
-
Returns
the
referrer
of
request
.
Its
value
can
be
a
same-origin
URL
if
explicitly
set
in
init
,
the
empty
string
to
indicate
no
referrer,
and
"
about:client
" when defaulting to the global’s default. This is used during fetching to determine the value of the `Referer
` header of the request being made. -
request . referrerPolicy
- Returns the referrer policy associated with request . This is used during fetching to compute the value of the request ’s referrer.
-
request . mode
- Returns the mode associated with request , which is a string indicating whether the request will use CORS, or will be restricted to same-origin URLs.
-
request . credentials
- Returns the credentials mode associated with request , which is a string indicating whether credentials will be sent with the request always, never, or only when sent to a same-origin URL.
-
request . cache
- Returns the cache mode associated with request , which is a string indicating how the the request will interact with the browser’s cache when fetching.
-
request . redirect
- Returns the redirect mode associated with request , which is a string indicating how redirects for the request will be handled during fetching. A request will follow redirects by default.
-
request . integrity
- Returns request ’s subresource integrity metadata, which is a cryptographic hash of the resource being fetched. Its value consists of multiple hashes separated by whitespace. [SRI]
-
request . keepalive
- Returns a boolean indicating whether or not request can outlive the global in which it was created.
-
request . isReloadNavigation
- Returns a boolean indicating whether or not request is for a reload navigation.
-
request . signal
-
Returns
the
signal
associated
with
request
,
which
is
an
AbortSignal
object indicating whether or not request has been aborted, and its abort event handler.
The
Request(
input
,
init
)
constructor
must
run
these
steps:
-
Let request be null.
-
Let fallbackMode be null.
-
Let fallbackCredentials be null.
-
Let baseURL be current settings object ’s API base URL .
-
Let signal be null.
-
If input is a string, then:
-
Otherwise ( input is a
Request
object): -
Let origin be current settings object ’s origin .
-
Let window be "
client
". -
If request ’s window is an environment settings object and its origin is same origin with origin , set window to request ’s window .
-
If init ’s
window
member is present and it is non-null, then throw aTypeError
. -
If init ’s
window
member is present, set window to "no-window
". -
Set request to a new request whose url is request ’s current url , method is request ’s method , header list is a copy of request ’s header list , unsafe-request flag is set, client is current settings object , window is window , origin is "
client
", referrer is request ’s referrer , referrer policy is request ’s referrer policy , mode is request ’s mode , credentials mode is request ’s credentials mode , cache mode is request ’s cache mode , redirect mode is request ’s redirect mode , integrity metadata is request ’s integrity metadata , keepalive flag is request ’s keepalive flag , and reload-navigation flag is request ’s reload-navigation flag . -
If any of init ’s members are present, then:
-
If request ’s mode is "
navigate
", then set it to "same-origin
". -
Unset request ’s reload-navigation flag .
-
Set request ’s referrer to "
client
" -
Set request ’s referrer policy to the empty string.
This is done to ensure that when a service worker "redirects" a request, e.g., from an image in a cross-origin stylesheet, and makes modifications, it no longer appears to come from the original source (i.e., the cross-origin stylesheet), but instead from the service worker that "redirected" the request. This is important as the original source might not even be able to generate the same kind of requests as the service worker. Services that trust the original source could therefore be exploited were this not done, although that is somewhat farfetched.
-
-
If init ’s
referrer
member is present, then:-
Let referrer be init ’s
referrer
member. -
If referrer is the empty string, then set request ’s referrer to "
no-referrer
". -
Otherwise:
-
Let parsedReferrer be the result of parsing referrer with baseURL .
-
If parsedReferrer is failure, then throw a
TypeError
. -
If one of the following conditions is true, then set request ’s referrer to "
client
":-
parsedReferrer
’s
cannot-be-a-base-URL
flag
is
set,
scheme
is
"
about
", and path contains a single string "client
". - parsedReferrer ’s origin is not same origin with origin
-
parsedReferrer
’s
cannot-be-a-base-URL
flag
is
set,
scheme
is
"
-
Otherwise, set request ’s referrer to parsedReferrer .
-
-
-
If init ’s
referrerPolicy
member is present, set request ’s referrer policy to it. -
Let mode be init ’s
mode
member if it is present, and fallbackMode otherwise. -
If mode is "
navigate
", then throw aTypeError
. -
If mode is non-null, set request ’s mode to mode .
-
Let credentials be init ’s
credentials
member if it is present, and fallbackCredentials otherwise. -
If credentials is non-null, set request ’s credentials mode to credentials .
-
If init ’s
cache
member is present, set request ’s cache mode to it. -
If request ’s cache mode is "
only-if-cached
" and request ’s mode is not "same-origin
", then throw aTypeError
. -
If init ’s
redirect
member is present, set request ’s redirect mode to it. -
If init ’s
integrity
member is present, set request ’s integrity metadata to it. -
If init ’s
keepalive
member is present, then set request ’s keepalive flag if init ’skeepalive
member is true, and unset it otherwise. -
If init ’s
method
member is present, then:-
Let method be init ’s
method
member. -
If method is not a method or method is a forbidden method , then throw a
TypeError
. -
Normalize method .
-
Set request ’s method to method .
-
-
If init ’s
signal
member is present, then set signal to it. -
Let r be a new
Request
object associated with request . -
Set r ’s headers to a new
Headers
object, whose header list is request ’s header list , and guard is "request
". -
If signal is not null, then make r ’s signal follow signal .
-
Let headers be a copy of r ’s headers and its associated header list .
-
If init ’s
headers
member is present, set headers to init ’sheaders
member. -
Empty r ’s headers ’s header list .
-
If headers is a
Headers
object, then for each header in its header list , append header ’s name / header ’s value to r ’sHeaders
object. -
Let inputBody be input ’s request ’s body if input is a
Request
object, and null otherwise. -
If either init ’s
body
member is present and is non-null or inputBody is non-null, and request ’s method is `GET
` or `HEAD
`, then throw aTypeError
. -
Let body be inputBody .
-
If init ’s
body
member is present and is non-null, then:-
Let Content-Type be null.
-
If init ’s
keepalive
member is present and is true, then set body and Content-Type to the result of extracting init ’sbody
member, with keepalive flag set. -
Otherwise, set body and Content-Type to the result of extracting init ’s
body
member. -
If Content-Type is non-null and r ’s headers ’s header list does not contain `
Content-Type
`, then append `Content-Type
`/ Content-Type to r ’s headers .
-
-
If body is non-null and body ’s source is null, then:
-
If r ’s request ’s mode is neither "
same-origin
" nor "cors
", then throw aTypeError
. -
Set r ’s request ’s use-CORS-preflight flag .
-
-
If inputBody is body and input is disturbed or locked , then throw a
TypeError
. -
If inputBody is non-null and inputBody is body , then:
-
Let rs bs a
ReadableStream
object from which one can read the exactly same data as one could read from inputBody ’s stream .This will be specified more precisely once transform stream and piping are precisely defined. See the issue .
This makes inputBody ’s stream locked and disturbed immediately.
-
Set body to a new body whose stream is rs , whose source is inputBody ’s source , and whose total bytes is inputBody ’s total bytes .
-
-
Set r ’s MIME type to the result of extracting a MIME type from r ’s request ’s header list .
-
Return r .
The
method
attribute’s
getter
must
return
request
’s
method
.
The
url
attribute’s
getter
must
return
request
’s
url
,
serialized
.
The
headers
attribute’s
getter
must
return
the
associated
headers
.
The
destination
attribute’s
getter
must
return
request
’s
destination
.
The
referrer
attribute’s
getter
must
return
the
empty
string
if
request
’s
referrer
is
"
no-referrer
",
"
about:client
"
if
request
’s
referrer
is
"
client
",
and
request
’s
referrer
,
serialized
,
otherwise.
The
referrerPolicy
attribute’s
getter
must
return
request
’s
referrer
policy
.
The
mode
attribute’s
getter
must
return
request
’s
mode
.
The
credentials
attribute’s
getter
must
return
request
’s
credentials
mode
.
The
cache
attribute’s
getter
must
return
request
’s
cache
mode
.
The
redirect
attribute’s
getter
must
return
request
’s
redirect
mode
.
The
integrity
attribute’s
getter
must
return
request
’s
integrity
metadata
.
The
keepalive
attribute’s
getter
must
return
true
if
request
’s
keepalive
flag
is
set,
and
false
otherwise.
The
isReloadNavigation
attribute’s
getter,
when
invoked,
must
return
true
if
the
context
object
’s
request
’s
reload-navigation
flag
is
set,
and
false
otherwise.
The
signal
attribute’s
getter
must
return
the
associated
signal
.
The
clone()
method,
when
invoked,
must
run
these
steps:
-
If this
Request
object is disturbed or locked , then throw aTypeError
. -
Let clonedRequestObject be a new
Request
object. -
Let clonedRequest be the result of cloning context object ’s request .
-
Set clonedRequestObject ’s request to clonedRequest .
-
Set clonedRequestObject ’s headers to a new
Headers
object whose header list is set to clonedRequest ’s header list , and guard is context object ’s headers ' guard . -
Make clonedRequestObject ’s signal follow context object ’s signal .
-
Return clonedRequestObject .
5.4. Response class
[Constructor(optional BodyInit?body
= null, optional ResponseInitinit
), Exposed=(Window,Worker)] interfaceResponse
{ [NewObject] static Response error(); [NewObject] static Response redirect(USVStringurl
, optional unsigned shortstatus
= 302); readonly attribute ResponseType type; readonly attribute USVString url; readonly attribute boolean redirected; readonly attribute unsigned short status; readonly attribute boolean ok; readonly attribute ByteString statusText; [SameObject] readonly attribute Headers headers; readonly attribute Promise<Headers> trailer; [NewObject] Response clone(); }; Response includes Body; dictionaryResponseInit
{ unsigned shortstatus
= 200; ByteStringstatusText
= "OK"; HeadersInitheaders
; }; enumResponseType
{"basic"
,"cors"
,"default"
,"error"
,"opaque"
,"opaqueredirect"
};
A
Response
object
has
an
associated
response
(a
response
).
A
Response
object
also
has
an
associated
headers
(null
or
a
Headers
object),
initially
null.
A
Response
object
also
has
an
associated
trailer
promise
(a
promise).
Used
for
the
trailer
attribute.
A
Response
object’s
body
is
its
response
’s
body
.
The
Response(
body
,
init
)
constructor,
when
invoked,
must
run
these
steps:
-
If init ’s
status
member is not in the range200
to599
, inclusive, then throw aRangeError
. -
If init ’s
statusText
member does not match the reason-phrase token production, then throw aTypeError
. -
Let r be a new
Response
object associated with a new response . -
Set r ’s headers to a new
Headers
object, whose header list is r ’s response ’s header list , and guard is "response
". -
Set r ’s response ’s status message to init ’s
statusText
member. -
If init ’s
headers
member is present, then fill r ’s headers with init ’sheaders
member. -
If body is non-null, then:
-
If init ’s
status
member is a null body status , then throw aTypeError
.101
is included in null body status due to its use elsewhere. It does not affect this step. -
Let Content-Type be null.
-
Set r ’s response ’s body and Content-Type to the result of extracting body .
-
If Content-Type is non-null and r ’s response ’s header list does not contain `
Content-Type
`, then append `Content-Type
`/ Content-Type to r ’s response ’s header list .
-
-
Set r ’s MIME type to the result of extracting a MIME type from r ’s response ’s header list .
-
Set r ’s response ’s HTTPS state to current settings object ’s HTTPS state .
-
Resolve r ’s trailer promise with a new
Headers
object whose guard is "immutable
". -
Return r .
The
static
error()
method,
when
invoked,
must
run
these
steps:
-
Let r be a new
Response
object, whose response is a new network error . -
Set r ’s headers to a new
Headers
object whose guard is "immutable
". -
Return r .
The
static
redirect(
url
,
status
)
method,
when
invoked,
must
run
these
steps:
-
Let parsedURL be the result of parsing url with current settings object ’s API base URL .
-
If parsedURL is failure, then throw a
TypeError
. -
If status is not a redirect status , then throw a
RangeError
. -
Let r be a new
Response
object, whose response is a new response . -
Set r ’s headers to a new
Headers
object whose guard is "immutable
". -
Set `
Location
` to parsedURL , serialized andUTF-8isomorphic encoded , in r ’s response ’s header list . -
Return r .
The
type
attribute’s
getter
must
return
response
’s
type
.
The
url
attribute’s
getter
must
return
the
empty
string
if
response
’s
url
is
null
and
response
’s
url
,
serialized
with
the
exclude-fragment
flag
set,
otherwise.
[URL]
The
redirected
attribute’s
getter
must
return
true
if
response
’s
url
list
has
more
than
one
item,
and
false
otherwise.
To
filter
out
responses
that
are
the
result
of
a
redirect,
do
this
directly
through
the
API,
e.g.,
fetch(url,
{
redirect:"error"
})
.
This
way
a
potentially
unsafe
response
cannot
accidentally
leak.
The
status
attribute’s
getter
must
return
response
’s
status
.
The
ok
attribute’s
getter
must
return
true
if
response
’s
status
is
an
ok
status
,
and
false
otherwise.
The
statusText
attribute’s
getter
must
return
response
’s
status
message
.
The
headers
attribute’s
getter
must
return
the
associated
Headers
object.
The
trailer
attribute’s
getter
must
return
the
associated
trailer
promise
.
The
clone()
method,
when
invoked,
must
run
these
steps:
-
If context object is disturbed or locked , then throw a
TypeError
. -
Let clonedResponseObject be a new
Response
object. -
Let clonedResponse be the result of cloning context object ’s response .
-
Set clonedResponseObject ’s response to clonedResponse .
-
Set clonedResponseObject ’s headers to a new
Headers
object whose header list is set to clonedResponse ’s header list , and guard is context object ’s headers ' guard . -
Upon fulfillment of context object ’s trailer promise , resolve clonedResponseObject ’s trailer promise with a new
Headers
object whose guard is "immutable
", and whose header list is clonedResponse ’s trailer . -
Return clonedResponseObject .
-
Return clonedResponse .
5.5. Fetch method
partial interface mixin WindowOrWorkerGlobalScope { [NewObject] Promise<Response> fetch(RequestInfoinput
, optional RequestInitinit
); };
The
fetch(
input
,
init
)
method,
must
run
these
steps:
-
Let p be a new promise.
-
Let requestObject be the result of invoking the initial value of
Request
as constructor with input and init as arguments. If this throws an exception, reject p with it and return p -
Let request be requestObject ’s request .
-
If requestObject ’s signal ’s aborted flag is set, then:
-
Abort fetch with p , request , and null.
-
Return p .
-
-
If
request
’s
client
’s
global
object
is
a
ServiceWorkerGlobalScope
object, then set request ’s service-workers mode to "none
". -
Let responseObject be a new
Response
object and a new associatedHeaders
object whose guard is "immutable
". -
Let locallyAborted be false.
This lets us reject promises with predictable timing, when the request to abort comes from the same thread as the call to fetch.
-
Add the following abort steps to requestObject ’s signal :
-
Set locallyAborted to true.
-
Abort fetch with p , request , and responseObject .
-
Terminate the ongoing fetch with the aborted flag set.
-
-
Run the following in parallel :
Fetch request .
To process response for response , run these substeps:
-
If locallyAborted is true, terminate these substeps.
-
If response ’s aborted flag is set, then abort fetch with p , request , and responseObject , and terminate these substeps.
-
If response is a network error , then reject p with a
TypeError
and terminate these substeps. -
Associate responseObject with response .
-
Resolve p with responseObject .
To process response done for response , run these substeps:
-
If locallyAborted is true, terminate these substeps.
-
Let trailerObject be a new
Headers
object whose guard is "immutable
". -
If response ’s trailer failed flag is set, then:
-
If response ’s aborted flag is set, reject responseObject ’s trailer promise with an "
AbortError
"DOMException
. -
Otherwise, reject responseObject ’s trailer promise with a
TypeError
. -
Terminate these substeps.
-
-
Associate trailerObject with response ’s trailer .
-
Resolve responseObject ’s trailer promise with trailerObject .
-
-
Return p .
To abort fetch with a promise , request , and responseObject , run these steps:
-
Let error be an "
AbortError
"DOMException
. -
Reject promise with error .
This is a no-op if promise has already fulfilled.
-
If request ’s body is not null and is readable , then cancel request ’s body with error .
-
If responseObject is null, then return.
-
Reject responseObject ’s trailer promise with error .
This is a no-op if responseObject ’s trailer promise has already fulfilled.
-
Let response be responseObject ’s response .
-
If response ’s body is not null and is readable , then error response ’s body with error .
5.6. Garbage collection
The user agent may terminate an ongoing fetch if that termination is not observable through script.
"Observable
through
script"
means
observable
through
fetch()
’s
arguments
and
return
value.
Other
ways,
such
as
communicating
with
the
server
through
a
side-channel
are
not
included.
The
server
being
able
to
observe
garbage
collection
has
precedent,
e.g.,
with
WebSocket
and
XMLHttpRequest
objects.
The user agent can terminate the fetch because the termination cannot be observed.
fetch("https://www.example.com/")
The user agent cannot terminate the fetch because the termination can be observed through the promise.
window.promise = fetch("https://www.example.com/")
The user agent can terminate the fetch because the associated body is not observable.
window.promise = fetch("https://www.example.com/").then(res => res.headers)
The user agent can terminate the fetch because the termination cannot be observed.
fetch("https://www.example.com/").then(res => res.body.getReader().closed)
The user agent cannot terminate the fetch because one can observe the termination by registering a handler for the promise object.
window.promise = fetch("https://www.example.com/") .then(res => res.body.getReader().closed)
The user agent cannot terminate the fetch as termination would be observable via the registered handler.
fetch("https://www.example.com/") .then(res => { res.body.getReader().closed.then(() => console.log("stream closed!")) })
(The
above
examples
of
non-observability
assume
that
built-in
properties
and
functions,
such
as
body.getReader()
,
have
not
been
overwritten.)
6. WebSocket protocol alterations
This section replaces part of the WebSocket protocol opening handshake client requirement to integrate it with algorithms defined in Fetch. This way CSP, cookies, HSTS, and other Fetch-related protocols are handled in a single location. Ideally the RFC would be updated with this language, but it is never that easy. The WebSocket API, defined in the HTML Standard, has been updated to use this language. [WSP] [HTML]
The way this works is by replacing The WebSocket Protocol’s "establish a WebSocket connection" algorithm with a new one that integrates with Fetch. "Establish a WebSocket connection" consists of three algorithms: setting up a connection, creating and transmiting a handshake request, and validating the handshake response. That layering is different from Fetch, which first creates a handshake, then sets up a connection and transmits the handshake, and finally validates the response. Keep that in mind while reading these alterations.
6.1. Connections
To obtain a WebSocket connection , given a url , run these steps:
-
Let host be url ’s host .
-
Let port be url ’s port .
-
Let secure be false, if url ’s scheme is "
http
", and true otherwise. -
Follow the requirements stated in step 2 to 5, inclusive, of the first set of steps in section 4.1 of The WebSocket Protocol to establish a WebSocket connection . [WSP]
-
If that established a connection, return it, and return failure otherwise.
Although structured a little differently, carrying different properties, and therefore not shareable, a WebSocket connection is very close to identical to an "ordinary" connection .
6.2. Opening handshake
To establish a WebSocket connection , given a url , protocols , and client , run these steps:
-
Let requestURL be a copy of url , with its scheme set to "
http
", if url ’s scheme is "ws
", and to "https
" otherwise.This change of scheme is essential to integrate well with fetching . E.g., HSTS would not work without it. There is no real reason for WebSocket to have distinct schemes, it’s a legacy artefact. [HSTS]
-
Let request be a new request , whose url is requestURL , client is client , service-workers mode is "
none
", referrer is "no-referrer
", synchronous flag is set, mode is "websocket
", credentials mode is "include
", cache mode is "no-store
", and redirect mode is "error
". -
Append `
Upgrade
`/`websocket
` to request ’s header list . -
Append `
Connection
`/`Upgrade
` to request ’s header list . -
Let keyValue be a nonce consisting of a randomly selected 16-byte value that has been base64-encoded (see section 4 of [RFC4648] ).
If the randomly selected value was the byte sequence 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10, keyValue would be `
AQIDBAUGBwgJCgsMDQ4PEC==
`. -
Append `
Sec-WebSocket-Key
`/ keyValue to request ’s header list . -
Append `
Sec-WebSocket-Version
`/`13
` to request ’s header list . -
For each protocol in protocols , combine `
Sec-WebSocket-Protocol
`/ protocol in request ’s header list . -
Let permessageDeflate be a user-agent defined "
permessage-deflate
" extension header value . [WSP] -
Append `
Sec-WebSocket-Extensions
`/ permessageDeflate to request ’s header list . -
Let response be the result of fetching request .
-
If response is a network error or its status is not
101
, fail the WebSocket connection . -
If protocols is not the empty list and extracting header list values given `
Sec-WebSocket-Protocol
` and response ’s header list results in null, failure, or the empty byte sequence, then fail the WebSocket connection .This is different from the check on this header defined by The WebSocket Protocol. That only covers a subprotocol not requested by the client. This covers a subprotocol requested by the client, but not acknowledged by the server.
-
Follow the requirements stated step 2 to step 6, inclusive, of the last set of steps in section 4.1 of The WebSocket Protocol to validate response . This either results in fail the WebSocket connection or the WebSocket connection is established .
Fail the WebSocket connection and the WebSocket connection is established are defined by The WebSocket Protocol. [WSP]
The reason redirects are not followed, HTTP authentication will not function, and this handshake is generally restricted is because that could introduce serious security problems in a web browser context. For example, consider a host with a WebSocket server at one path and an open HTTP redirector at another. Suddenly, any script that can be given a particular WebSocket URL can be tricked into communicating to (and potentially sharing secrets with) any host on the internet, even if the script checks that the URL has the right hostname.
7.
data:
URLs
For
an
informative
description
of
data:
URLs,
see
RFC
2397.
This
section
replaces
that
RFC’s
normative
processing
requirements
to
be
compatible
with
deployed
content.
[RFC2397]
A
data:
URL
struct
is
a
struct
that
consists
of
a
MIME
type
(a
MIME
type
)
and
a
body
(a
byte
sequence
).
The
data:
URL
processor
takes
a
URL
dataURL
and
then
runs
these
steps:
-
Assert: dataURL ’s scheme is "
data
". -
Let input be the result of running the URL serializer on dataURL with the exclude fragment flag set.
-
Remove the leading "
data:
" string from input . -
Let position point at the start of input .
-
Let mimeType be the result of collecting a sequence of code points that are not equal to U+002C (,), given position .
-
Strip leading and trailing ASCII whitespace from mimeType .
This will only remove U+0020 SPACE code points , if any.
-
If position is past the end of input , then return failure.
-
Advance position by 1.
-
Let encodedBody be the remainder of input .
-
Let body be the string percent decoding of encodedBody .
-
If mimeType ends with U+003B (;), followed by zero or more U+0020 SPACE, followed by an ASCII case-insensitive match for "
base64
", then:-
Let stringBody be the isomorphic decode of body .
-
Set body to the forgiving-base64 decode of stringBody .
-
If body is failure, then return failure.
-
Remove the last 6 code points from mimeType .
-
Remove trailing U+0020 SPACE code points from mimeType , if any.
-
Remove the last U+003B (;) code point from mimeType .
-
-
If mimeType starts with U+003B (;), then prepend "
text/plain
" to mimeType . -
Let mimeTypeRecord be the result of parsing mimeType .
-
If mimeTypeRecord is failure, then set mimeTypeRecord to
text/plain;charset=US-ASCII
. -
Return a new
data:
URL struct whose MIME type is mimeTypeRecord and body is body .
Background reading
This section and its subsections are informative only.
HTTP header layer division
For
the
purposes
of
fetching,
there
is
an
API
layer
(HTML’s
img
,
CSS'
background-image
),
early
fetch
layer,
service
worker
layer,
and
network
&
cache
layer.
`
Accept
`
and
`
Accept-Language
`
are
set
in
the
early
fetch
layer
(typically
by
the
user
agent).
Most
other
headers
controlled
by
the
user
agent,
such
as
`
Accept-Encoding
`,
`
Host
`,
and
`
Referer
`,
are
set
in
the
network
&
cache
layer.
Developers
can
set
headers
either
at
the
API
layer
or
in
the
service
worker
layer
(typically
through
a
Request
object).
Developers
have
almost
no
control
over
forbidden
headers
,
but
can
control
`
Accept
`
and
have
the
means
to
constrain
and
omit
`
Referer
`
for
instance.
Atomic HTTP redirect handling
Redirects (a response whose status or internal response ’s (if any) status is a redirect status ) are not exposed to APIs. Exposing redirects might leak information not otherwise available through a cross-site scripting attack.
A
fetch
to
https://example.org/auth
that
includes
a
Cookie
marked
HttpOnly
could
result
in
a
redirect
to
https://other-origin.invalid/4af955781ea1c84a3b11
.
This
new
URL
contains
a
secret.
If
we
expose
redirects
that
secret
would
be
available
through
a
cross-site
scripting
attack.
Basic safe CORS protocol setup
For resources where data is protected through IP authentication or a firewall (unfortunately relatively common still), using the CORS protocol is unsafe . (This is the reason why the CORS protocol had to be invented.)
However, otherwise using the following header is safe :
Access-Control-Allow-Origin: *
Even
if
a
resource
exposes
additional
information
based
on
cookie
or
HTTP
authentication,
using
the
above
header
will
not
reveal
it.
It
will
share
the
resource
with
APIs
such
as
XMLHttpRequest
,
much
like
it
is
already
shared
with
curl
and
wget
.
Thus
in
other
words,
if
a
resource
cannot
be
accessed
from
a
random
device
connected
to
the
web
using
curl
and
wget
the
aforementioned
header
is
not
to
be
included.
If
it
can
be
accessed
however,
it
is
perfectly
fine
to
do
so.
CORS protocol and HTTP caches
If
CORS
protocol
requirements
are
more
complicated
than
setting
`
Access-Control-Allow-Origin
`
to
*
or
a
static
origin
,
`
Vary
`
is
to
be
used.
[HTML]
[HTTP]
[HTTP-SEMANTICS]
[HTTP-COND]
[HTTP-CACHING]
[HTTP-AUTH]
Vary: Origin
In
particular,
consider
what
happens
if
`
Vary
`
is
not
used
and
a
server
is
configured
to
send
`
Access-Control-Allow-Origin
`
for
a
certain
resource
only
in
response
to
a
CORS
request
.
When
a
user
agent
receives
a
response
to
a
non-
CORS
request
for
that
resource
(for
example,
as
the
result
of
a
navigation
request
),
the
response
will
lack
`
Access-Control-Allow-Origin
`
and
the
user
agent
will
cache
that
response.
Then,
if
the
user
agent
subsequently
encounters
a
CORS
request
for
the
resource,
it
will
use
that
cached
response
from
the
previous
non-
CORS
request
,
without
`
Access-Control-Allow-Origin
`.
But
if
`
Vary:
Origin
`
is
used
in
the
same
scenario
described
above,
it
will
cause
the
user
agent
to
fetch
a
response
that
includes
`
Access-Control-Allow-Origin
`,
rather
than
using
the
cached
response
from
the
previous
non-
CORS
request
that
lacks
`
Access-Control-Allow-Origin
`.
However,
if
`
Access-Control-Allow-Origin
`
is
set
to
*
or
a
static
origin
for
a
particular
resource,
then
configure
the
server
to
always
send
`
Access-Control-Allow-Origin
`
in
responses
for
the
resource
—
for
non-
CORS
requests
as
well
as
CORS
requests
—
and
do
not
use
`
Vary
`.
Acknowledgments
Thanks to Adam Barth, Adam Lavin, Alan Jeffrey, Alexey Proskuryakov, Andrés Gutiérrez, Andrew Sutherland, Ángel González, Anssi Kostiainen, Arkadiusz Michalski, Arne Johannessen, Arthur Barstow, Axel Rauschmayer, Ben Kelly, Benjamin Gruenbaum, Benjamin Hawkes-Lewis, Bert Bos, Björn Höhrmann, Boris Zbarsky, Brad Hill, Brad Porter, Bryan Smith, Caitlin Potter, Cameron McCormack, Chris Rebert, Clement Pellerin, Collin Jackson, Daniel Robertson, Daniel Veditz, David Benjamin, David Håsäther, David Orchard, Dean Jackson, Devdatta Akhawe, Domenic Denicola, Dominic Farolino, Dominique Hazaël-Massieux, Doug Turner, Eero Häkkinen, Ehsan Akhgari, Emily Stark, Eric Lawrence, François Marier, Frank Ellerman, Frederick Hirsch, Gavin Carothers, Glenn Maynard, Graham Klyne, Hal Lockhart, Hallvord R. M. Steen, Harris Hancock, Henri Sivonen, Henry Story, Hiroshige Hayashizaki, Honza Bambas, Ian Hickson, Ilya Grigorik, isonmad, Jake Archibald, James Graham, Janusz Majnert, Jeena Lee, Jeff Carpenter, Jeff Hodges, Jeffrey Yasskin, Jesse M. Heines, Jinho Bang, Jochen Eisinger, Jonas Sicking, Jonathan Kingston, Jonathan Watt, 최종찬 (Jongchan Choi), Jörn Zaefferer, Joseph Pecoraro, Josh Matthews, Julian Krispel-Samsel, Julian Reschke, 송정기 (Jungkee Song), Jussi Kalliokoski, Jxck, Keith Yeung, Kenji Baheux, Lachlan Hunt, Larry Masinter, Liam Brummitt, Louis Ryan, Lucas Gonze, Łukasz Anforowicz, 呂康豪 (Kang-Hao Lu), Maciej Stachowiak, Malisa, Manfred Stock, Manish Goregaokar, Marc Silbey, Marcos Caceres, Marijn Kruisselbrink, Mark Nottingham, Mark S. Miller, Martin Dürst, Martin Thomson, Matt Andrews, Matt Falkenhagen, Matt Oshry, Matt Seddon, Matt Womer, Mhano Harkness, Michael Kohler, Michael™ Smith, Mike Pennisi, Mike West, Mohamed Zergaoui, Moritz Kneilmann, Ms2ger, Nico Schlömer, Nikhil Marathe, Nikki Bee, Nikunj Mehta, Odin Hørthe Omdal, Ondřej Žára, Philip Jägenstedt, R. Auburn, Raphael Kubo da Costa, Ryan Sleevi, Rory Hewitt, Sébastien Cevey, Sendil Kumar N, Shao-xuan Kang, Sharath Udupa, Shivakumar Jagalur Matt, Sigbjørn Finne, Simon Pieters, Simon Sapin, Srirama Chandra Sekhar Mogali, Steven Salat, Sunava Dutta, Surya Ismail, 吉野剛史 (Takeshi Yoshino), Thomas Roessler, Thomas Wisniewski, Tiancheng "Timothy" Gu, Tobie Langel, Tom Schuster, Tomás Aparicio, 保呂毅 (Tsuyoshi Horo), Tyler Close, Vignesh Shanmugam, Vladimir Dzhuvinov, Wayne Carr, Xabier Rodríguez, Yehuda Katz, Yoav Weiss, Youenn Fablet, 平野裕 (Yutaka Hirano), and Zhenbin Xu for being awesome.
This standard is written by Anne van Kesteren ( Mozilla , annevk@annevk.nl ).
Copyright © 2018 WHATWG (Apple, Google, Mozilla, Microsoft). This work is licensed under a Creative Commons Attribution 4.0 International License .