To the extent possible under law, the editor has waived all copyright and
related or neighboring rights to this work. In addition, as of
9 May 2013, the editor has made this specification available
under the
Open Web Foundation Agreement Version 1.0,
which is available at
http://www.openwebfoundation.org/legal/the-owf-1-0-agreements/owfa-1-0.
The Fetch standard defines the overall architecture for obtaining resources given a URL and a set of parameters. This concept is named fetching.
To unify fetching across the web platform this specification supplants a number of algorithms and specifications:
Origin header semantics
Unifying fetching provides consistent handling of:
In due course, it should also help clarify the semantics of CSP and make provide a model to hook offline networking into.
HTML defines two algorithms. This maps these "legacy" algorithms to the new fetch.
When a user agent is to fetch a resource or URL, optionally from an origin origin, optionally using a specific referrer source as an override referrer source, and optionally with any of a synchronous flag, a manual redirect flag, a force same-origin flag, and a block cookies flag, the following steps must be run:
The block cookies flag is obsolete now.
If there is a specific override referrer source, and it is a URL, then let referrer be the override referrer source.
Otherwise, run these substeps:
Let document be the appropriate Document as given by
the following list:
While document is
an iframe srcdoc document, set
document to
document's browsing context's
browsing context container's Document instead.
If document's origin is not a scheme/host/port tuple, then let referrer be null.
Otherwise, let referrer be the document's address of document.
If referrer's scheme is about/data/javascript, set referrer to null.
If the Document with which any tasks
queued by this algorithm would be associated doesn't
have an associated browsing context, then terminate these steps.
Let req be a new request.
If this algorithm was invoked with "from an origin", set req's origin to origin.
Set req's referrer to referrer.
Set req's mode to same-origin if the force same-origin flag is set, and to tainted cross-origin otherwise.
Set req's manual redirect flag if manual redirect flag is set.
Set req's synchronous flag if synchronous flag is set.
fetch req.
When the user agent is required to perform a potentially CORS-enabled fetch of an URL with a mode mode that is either "No CORS", "Anonymous", or "Use Credentials", optionally using a referrer source referrer source, with an origin origin, and with a default origin behaviour default which is either "taint" or "fail", it must run these steps:
Let req be a new request.
Set req's origin to origin.
Set req's mode to the value corresponding to the first matching statement:
If mode is "Anonymous", set req's omit credentials mode to always.
fetch req.
All diagrams, examples, and notes in this specification are non-normative, as are all sections explicitly marked non-normative. Everything else in this specification is normative.
The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in the normative parts of this specification are to be interpreted as described in RFC2119. For readability, these words do not appear in all uppercase letters in this specification. [RFC2119]
This specification uses terminology from the Encoding and URL Standards. [ENCODING] [URL]
A byte string is a byte sequence written down as a string. To avoid confusion with an actual string quotation marks are omitted.
"true" is a
string, while true is a
byte string.
A case-insensitive byte string is a byte string that when compared considers bytes in the range 0x41 to 0x5A to be a match for their corresponding byte in the range 0x61 to 0x7A.
The
case-insensitive byte strings
Content-Type and content-TYPE are equal.
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. via data URL).
A method is a byte string.
A header consists of a name and value. A name is a case-insensitive byte string and a value is a byte string.
A simple method is a method that is
GET, HEAD, or POST.
A simple header is a header whose
name is Accept,
Accept-Language, or Content-Language, or whose
name is Content-Type and
value, once parsed, is
application/x-www-form-urlencoded,
multipart/form-data,
or text/plain.
What we never resolved in the old specification was whether only certain parameters should be allowed and how exactly the MIME type parsing would work. Hopefully parsing MIME types will solve this.
To parse a header value parse it per the ABNF and return the values obtained for the given name, and return failure if the value did not match the ABNF.
The input to fetch is a request.
A request has an associated
method. Unless stated otherwise a
request's
method is GET.
A request has an associated url (a parsed URL).
A request has associated author headers and headers. Unless stated otherwise request's author headers and headers are empty lists of headers.
A request has an associated
origin, and
force Origin header flag. Unless stated otherwise a
request's
origin is null and its
force Origin header flag is unset.
A request has an associated referrer. Unless stated otherwise it is null.
A request has an associated body. Unless stated otherwise a request's body is null.
A request has an associated synchronous flag. Unless stated otherwise a request's synchronous flag is unset.
A request has an associated mode, which is one of same-origin, tainted cross-origin, and CORS. Unless stated otherwise, request's mode is tainted cross-origin.
A request has an associated force preflight flag. Unless stated otherwise, it is unset and only relevant when request's mode is CORS.
A request has an associated omit credentials mode, which is one of always, CORS, and never.
I think we want the default to become always, but currently it is never.
A arequest has an associated use URL credentials flag. Unless stated otherwise, it is unset.
A request has an associated manual redirect flag. Unless stated otherwise, it is unset.
A request has an associated redirect count. Unless stated otherwise a request's redirect count is zero.
The result of fetch is a response. A response is build incrementally over time. All its fields are not necessarily available straight away.
A response has an associated type which is one of default, redirect, and error. Unless stated otherwise, it is default.
A response has an associated status, status message, location, headers, and a body.
A response is either CORS-same-origin or CORS-cross-origin. Unless otherwise indicated a response is CORS-same-origin.
When introducing new APIs, unless there is a very good reason, only use
responses that are CORS-same-origin and
treat others as network errors. This distinction
is used today e.g. to allow responses from a different
origin not fetched using
request's mode
CORS to still be displayed using the HTML img element, but
not have their body extracted using the HTML
canvas element.
Unless stated otherwise, a response's
status is 200,
status message is OK,
location is null,
headers is an empty list, and
body is null,
A response whose type is error is known as a network error.
A network error's
status is 0,
status message is the empty byte string,
location is null,
headers is an empty list, and
body is null,
A response whose type is redirect is known as a redirect.
Origin headerThe Origin request
header indicates where a
fetch originates from.
The Origin header is a stripped-down version
of the Referer [sic] header as to not reveal confidential
path information. It is used for
all basic fetches whose CORS flag is
set as well as fetches where
request's
method is POST. Due to
compatibility constraints it is not included in all fetches.
Its value ABNF:
Origin = origin-or-null origin-or-null = origin / %x6E.75.6C.6C ; "null", case-sensitive origin = scheme "://" host [ ":" port ]
This replaces the syntax defined for the Origin header by
The Web Origin Concept. Unfortunately that document cannot be updated to match reality
without involving layers and layers of bureaucracy.
[ORIGIN]
To allow sharing resources cross-origin and allow for more versetile HTTP requests than
possible with HTML's form element, the platform has
a CORS protocol layered on top of HTTP. It allows resources to declare they
can be shared with resources residing on a different origin.
It needs to be an opt-in mechanism to prevent leaking data from resources behind a firewall (intranets). Additionally, for credentialed HTTP requests it needs to be opt-in to prevent leaking potentially-sensitive data.
This section explains the CORS protocol as it pertains to servers. Requirements for user agents are part of the fetch algorithm.
The CORS protocol consists of a set of headers that indicates whether a particular resource can be shared cross-origin.
For HTTP requests that are more involved than what is possible with HTML's
form element, a CORS preflight fetch is
performed, to ensure the resource understands the CORS protocol.
A HTTP request can be identified as pertaining in the CORS protocol if it
includes an Origin header.
A HTTP request can be identified as being a CORS preflight (a check to see if the
CORS protocol is understood) if it pertains in the CORS protocol
(includes an Origin header), uses
OPTIONS as method, and includes these
headers:
Access-Control-Request-Method
Indicates which method a future HTTP request to the same resource might use.
Access-Control-Request-Headers
Indicates which headers a future HTTP request to the same resource might use.
A HTTP response to a HTTP request pertaining in the CORS protocol can include the following headers:
Access-Control-Allow-Origin
Indicates whether a resource can be shared, via returning the
value (literally) of the
Origin request
header, *, or
null in a response.
Access-Control-Allow-Credentials
Indicates whether a resource can be shared when request's omit credentials mode is never.
For a CORS preflight request's omit credentials mode is always never, but for any subsequent HTTP requests it might not be. Support therefore needs to be indicated for the CORS preflight as well.
A HTTP response to a CORS preflight can include the following headers:
Access-Control-Allow-Methods
Indicates which methods are supported by the resource for the purposes of the CORS protocol.
Access-Control-Allow-Headers
Indicates which headers are supported by the resource 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.
A HTTP response to a HTTP request pertaining in the CORS protocol that is not a CORS preflight can also include the following header:
Access-Control-Expose-Headers
Indicates which headers can be exposed as part of the HTTP response, via listing their names.
ABNF for the values of the headers used by the CORS protocol:
Access-Control-Request-Method = Method Access-Control-Request-Headers = #field-name Access-Control-Allow-Origin = origin-or-null / "*" 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
To perform a fetch using request, optionally with a CORS flag, run these steps:
The CORS flag within the fetch algorithm is used for handling redirects. When using fetch externally only the request parameter should be passed.
Let url be request's url.
Let origin be request's origin.
If request's synchronous flag is unset and fetch is not invoked recursively, run the remaining steps asynchronously.
Let response be the value corresponding to the first matching statement:
about", "blob", and "data",
and request's redirect count is zero
The result of performing a basic fetch using request.
The result of performing a basic fetch using request, marked CORS-cross-origin.
http" and "https"
The result of performing a CORS fetch with preflight using request.
The result of performing a basic fetch using request with the CORS flag set.
If fetch is invoked recursively, return response.
If request's synchronous flag is set, wait for response to have been fully transmitted and then return it.
Keep queueing tasks on the networking task source until the response has been fully transmitted. If no transmission is taking place, queue at least one task.
To perform a basic fetch using request, with an optional CORS flag and HTTP authentication flag, switch on request's url's scheme and run the associated steps:
about"
If request's url's
scheme data is
"blank", return a response whose
headers consist of a single
header whose
name is Content-Type and
value is
"text/html;charset=utf-8", and
body is the empty string.
Otherwise, return a network error.
blob"
It has been argued this should be handled outside of fetching.
data"
If request's method is
GET and
obtaining a resource from
request's url does not return
failure, return a response whose
headers consist of a single
header whose
name is Content-Type and
value is the MIME type and parameters returned
from obtaining a resource, and
body is the data returned from
obtaining a resource.
Otherwise, return a network error.
file"
For now, unfortunate as it is, file
URLs are left as an exercise for the
reader.
When in doubt, return a network error.
ftp"
Follow the requirements from FTP to retrieve a resource.
Map the result to response.
http"
https"
Set up an HTTP request following the requirements from HTTP and TLS as appropriate, with these additional constraints:
If request's
referrer is not null, include a
Referer header
whose value is request's
referrer.
User agents are encouraged to provide the end user with options to
always exclude Referer headers
or have it expose less sensitive information.
If request's force Origin header flag is
set, include an Origin header
whose value is request's
origin,
serialized to bytes.
Include all of request's headers and let them replace any headers with the same name already present in the HTTP request.
Include all of request's author headers as long as their name is not present in the HTTP request.
If request's omit credentials mode is always or request's omit credentials mode is CORS and the CORS flag is unset, run these substeps:
Include Cookie headers associated with
request's url.
[COOKIES]
If there's an authentication entry for request's
url and either
request's use URL credentials flag is unset or
request's url
does not include credentials, include the Authorization header from the
authentication entry.
Otherwise, if request's url
includes credentials, and the HTTP authentication flag is set, include an
Authorization header using those credentials.
If there's a proxy authentication entry, use it as appropriate. [HTTP]
This intentionally does not depend on request's omit credentials mode.
If the HTTP request is terminated before all headers from the resource are obtained, return a network error.
Otherwise, when the headers from the resource are obtained, let response be a new response and set its fields appropriately.
If there are cookies to be set and either the CORS flag is set and request's omit credentials mode is CORS or request's omit credentials mode is always, run these steps:
Wait until ownership of the storage mutex can be taken by this instance of the fetch algorithm.
Take ownership of the storage mutex.
Update the cookies. [COOKIES]
This is a fingerprinting vector.
Release the storage mutex so that it is once again free.
If the CORS flag is set and a CORS check for request and response returns failure, return a network error.
If response's status is 301, 302, 303, 307, or 308, run these steps:
If response's
headers do not contain a
header whose
name is Location, return
response.
If response's
headers contain more than one
header whose
name is Location, return a
network error.
Let location be the
value of the
header whose
name is Location within
response's headers.
Let parsed location be the result of parsing location with request's url.
If parsed location is failure, return a network error.
If request's redirect count is twenty, return a network error.
Increase request's redirect count by one.
Set response's type to redirect.
Set response's location to parsed location.
If request's manual redirect flag is unset, run these substeps:
If the CORS flag is set and response's location's origin is not request's url's origin, set request's origin to a globally unique identifier.
If the CORS flag is set and response's location's username or password is non-null, return a network error.
Return the result of performing a fetch using request, with the CORS flag set if set.
Otherwise, if response's status is 401, run these steps:
If the CORS flag is set, return response.
Needs testing: multiple WWW-Authenticate headers,
missing, parsing issues.
If request's use URL credentials flag is unset, or the HTTP authentication flag is set, run these substeps:
Return the result of performing a basic fetch using request, with the HTTP authentication flag set.
Otherwise, if response's status is 407, run these steps:
Needs testing: multiple Proxy-Authenticate headers,
missing, parsing issues.
Prompt the end user as appropriate and store the result as appropriate as a proxy authentication entry. [HTTP]
Remaining details surrounding proxy authentication are defined by HTTP.
Return the result of performing basic fetch using request.
If the HTTP authentication flag is set, create an authentication entry for request's url and the given realm. [HTTPAUTH]
Return response.
Return a network error.
To perform a CORS fetch with preflight using request, run these steps:
If
then run these substeps:
Let response be a CORS preflight fetch using request.
If response is a network error, return response.
Set request's manual redirect flag.
Let response be a basic fetch using request with the CORS flag set.
If response is a network error, clear using request.
Return response.
To perform a CORS preflight fetch using request, run these steps:
Let preflight be a new request.
Set preflight's method to
OPTIONS.
Append a header
named
Access-Control-Request-Method with
value request's
method to preflight's
headers.
Let headers be the names of request's author headers, sorted lexicographically and byte lowercased.
Let header value be the items in headers separated from each other by 0x2C 0x20.
Append a header
named
Access-Control-Request-Headers with
value header value to
preflight's headers.
Set preflight's manual redirect flag.
Let response be the result of performing a basic fetch using preflight with the CORS flag set.
If response's status is in the range 200 to 299, run these substeps:
Let methods be the result of
parsing all response's
headers'
named Access-Control-Allow-Methods.
Let header names be the result of
parsing all response's
headers'
named Access-Control-Allow-Headers.
If either methods or header names is failure, return a network error.
If methods is empty request's force preflight flag is set, append request's method to methods.
This ensures that a CORS preflight fetch that happened solely because of request's force preflight flag is too.
If request's method is not in methods and is not a simple method, return failure.
If one of request's headers' names is not in header names or its corresponding header is not a simple header, return a network error.
Let max-age be the result of
parsing all response's
headers'
named Access-Control-Max-Age.
If max-age is failure, set max-age to zero.
If max-age is greater than an imposed limit on max-age, set max-age to the imposed limit.
If the user agent does not provide for a cache, 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 in the CORS preflight cache as follows:
For each header name in header names for which there is a header name cache match using request, set matching entry's max-age to max-age.
For each header name in header names for which there is no header name cache match using request, create a new entry in the CORS preflight cache as follows:
Return response.
Otherwise, return a network error.
A CORS preflight cache consists of a collection of entries where each entry has these fields: origin, url, max-age, credentials, method, and 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 clear entries using a request, remove any entries in the CORS preflight cache whose origin is request's origin and whose url is request's url.
There is a cache match for a request if origin is request's origin, url is request's url, and either credentials is false and request's omit credentials mode is not never or credentials is true and request's omit credentials mode is never.
There is a method cache match for a given 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 the given method.
There is a header name cache match for a given header name using request when there is an entry in CORS preflight cache for which there is a cache match for request and its header name is the given header name.
To perform a CORS check for a request and response, run these steps:
If response's headers
contains zero or more than one header whose
name is Access-Control-Allow-Origin,
return failure.
Let result be the value
of the header whose
name is Access-Control-Allow-Origin
within response's headers.
If request's
omit credentials mode is not
never and result is *, return success.
If request's origin serialized to bytes is not result, return failure.
If request's omit credentials mode is not never, return success.
If response's headers
contains zero or more than one header whose
name is Access-Control-Allow-Credentials,
return failure.
If the value
of the header whose
name is Access-Control-Allow-Origin
within response's headers is
true, return success.
Return failure.
The editor would like to thank Adam Barth, Alexey Proskuryakov, Arne Johannessen, Arthur Barstow, Benjamin Hawkes-Lewis, Bert Bos, Björn Höhrmann, Boris Zbarsky, Brad Hill, Brad Porter, Cameron McCormack, Collin Jackson, David Håsäther, David Orchard, Dean Jackson, Eric Lawrence, Frank Ellerman, Frederick Hirsch, Gavin Carothers, Glenn Maynard, Graham Klyne, Hal Lockhart, Henri Sivonen, Ian Hickson, Jesse M. Heines, Jonas Sicking, Julian Reschke, Lachlan Hunt, 呂康豪 (Kang-Hao Lu), Maciej Stachowiak, Marc Silbey, Marcos Caceres, Mark Nottingham, Mark S. Miller, Martin Dürst, Matt Oshry, Matt Womer, Mhano Harkness, Michael Smith, Mohamed Zergaoui, Nikunj Mehta, Odin Hørthe Omdal, Philip Jägenstedt, R. Auburn, Sharath Udupa, Simon Pieters, Sunava Dutta, Surya Ismail, Thomas Roessler, Tyler Close, Vladimir Dzhuvinov, Wayne Carr, and Zhenbin Xu for being awesome.