Abstract

The Fetch standard defines the overall architecture for obtaining resources given a URL and a set of parameters. This concept is named fetching.

Goals

To unify fetching across the web platform this specification supplants a number of algorithms and specifications:

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.

Legacy

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.

  1. If there is a specific override referrer source, and it is a URL, then let referrer be the override referrer source.

  2. Otherwise, run these substeps:

    1. Let document be the appropriate Document as given by the following list:

      If there is a specific override referrer source
      The override referrer source.
      When navigating
      The active document of the source browsing context.
      When fetching resources for an element
      The element's node document.
    2. While document is an iframe srcdoc document, set document to document's browsing context's browsing context container's Document instead.

    3. If document's origin is not a scheme/host/port tuple, then let referrer be null.

    4. Otherwise, let referrer be the document's address of document.

    5. If referrer's scheme is about/data/javascript, set referrer to null.

  3. 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.

  4. Let req be a new request.

  5. If this algorithm was invoked with "from an origin", set req's origin to origin.

  6. Set req's referrer to referrer.

  7. Set req's mode to same-origin if the force same-origin flag is set, and to tainted cross-origin otherwise.

  8. Set req's manual redirect flag if manual redirect flag is set.

  9. Set req's synchronous flag if synchronous flag is set.

  10. 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:

  1. Let req be a new request.

  2. Set req's origin to origin.

  3. Set req's mode to the value corresponding to the first matching statement:

    mode is "No CORS" and default is "fail"
    same-origin
    mode is "No CORS" and default is "taint"
    tainted cross-origin
    Otherwise
    CORS
  4. If mode is "Anonymous", set req's omit credentials flag.

  5. Determine req's referrer as per fetch.

  6. Fetch req.

Requests

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 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.

referrer or referrer source? maybe easier to stick to the latter

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 body. Unless stated otherwise a request's body is null.

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 and an omit credentials flag. Unless stated otherwise, request's force preflight flag and omit credentials flag are unset. Request's force preflight flag and omit credentials flag are only relevant when request's mode is CORS.

A request has an associated redirect count. Unless stated otherwise a request's redirect count is zero.

Responses

The result of fetch is a response.

A response has an associated status, status message, headers, and a body.

When a response becomes available, its body not necessarily is.

A response has three subtypes, namely redirect, network error, and end-user abort.

A redirect has an associated location (a parsed URL).

A response is either CORS-same-origin or CORS-cross-origin. Unless otherwise indicated a response is CORS-same-origin.

Fetching

To perform a fetch using request, run these steps:

  1. Let url be request's url.

  2. Let origin be request's origin.

  3. If request's synchronous flag is unset and fetch is not invoked recursively, run the remaining steps asynchronously.

  4. Let response be the value corresponding to the first matching statement:

    url's origin is origin
    url's scheme is one of "about", "blob", and "data"

    The result of performing a redirect fetch using request.

    request's mode is "same-origin"

    A network error.

    request's mode is "tainted cross-origin"

    The result of performing a redirect fetch using request, marked CORS-cross-origin.

    url's scheme is not one of "http" and "https"

    A network error.

    request's force preflight flag is set.
    request's method is not a simple method.
    A header in request's author headers is not a simple header.

    The result of performing a CORS fetch with preflight using request.

    Otherwise

    The result of performing a CORS fetch using request.

  5. If fetch is invoked recursively, return response.

  6. If request's synchronous flag is set, wait for response to have been fully transmitted and then return it.

  7. 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.

Basic fetch

To perform a basic fetch using request, 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 status is 200, status message is "OK", 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 status is 200, status message is "OK", 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 (and their platform).

When in doubt, return a network error.

"ftp"

Follow the requirements from FTP to retrieve a resource.

Map the result to response.

"http"
"https"

Follow the requirements from HTTP to retrieve a resource. If the end user terminates the connection, return a end-user abort. If the connection terminates for other reason, return a network error. Otherwise, when the headers from the resource are obtained, let response be a new response and set its fields appropriately.

Need to deal with setting Origin / Referer properly, and merging custom / ua headers.

cookies?!

If response's status is 301, 302, 303, 307, or 308, run these steps:

  1. If response's headers do not contain a header whose name is Location, return response.

  2. If response's headers contain more than one header whose name is Location, change response into a network error and return it.

  3. Let location be the value of the header whose name is Location within response's headers.

  4. Let parsed location be the result of parsing location with request's url.

  5. If parsed location is failure, change response into a network error and return it.

  6. If request's redirect count is twenty, change response into a network error and return it.

  7. Increase request's redirect count by one.

  8. Change response into a redirect.

  9. Set response's location to parsed location.

Return response.

Otherwise

Return a network error.

Redirect fetch

To perform a redirect fetch using request, run these steps:

  1. Let response be the result of performing a basic fetch using request.

  2. If response is a redirect and request's manual redirect flag is unset, run these substeps:

    1. If response's location's origin is not request's url's origin, set request's origin to a globally unique identifier.

    2. Set request's url to response's location.

    3. Return the result of performing a fetch using request.

  3. Return response.

CORS fetch

To perform a CORS fetch using request, run these steps:

  1. Let response be the result of performing a basic fetch using request.

  2. If response is a redirect and request's manual redirect flag is unset, run these substeps:

    1. If response's location's origin is not request's url's origin, set request's origin to a globally unique identifier.

    2. If response's location's username or password is non-null, or if a CORS check for request and response returns failure, change response into a network error and then return it.

    3. Set request's url to response's location.

    4. Return the result of performing a CORS fetch using request.

  3. Otherwise, run these substeps:

    1. If response is not an end-user abort and CORS check for request and response returns failure, change response into a network error.

    2. Return response.

CORS fetch with preflight

To perform a CORS fetch with preflight using request, run these steps:

  1. If

    then run these substeps:

    1. Let response be a CORS preflight fetch using request.

    2. If response is either an end-user abort or network error, return it.

  2. Let response be a basic fetch using request.

  3. If response is a redirect, change response into a network error.

  4. If response is response and a CORS check for request and response returns failure, change response into a network error.

  5. If response is a network error, clear using request.

  6. Return response.

CORS preflight fetch

To perform a CORS preflight fetch using request, run these steps:

  1. Let preflight be a new request.

  2. Set preflight's url to request's url.

  3. Set preflight's origin to request's origin.

  4. Set preflight's referrer to request's referrer.

  5. Set preflight's method to OPTIONS.

  6. Append a header named Access-Control-Request-Method with value request's method to preflight's headers.

  7. Let headers be the names of request's author headers, sorted lexicographically and byte lowercased.

  8. Let header value be the items in headers separated from each other by 0x2C 0x20.

  9. Append a header named Access-Control-Request-Headers with value header value to preflight's headers.

  10. Let response be the result of performing a basic fetch using preflight.

  11. If a CORS check for preflight and response does not return failure, and response's status is in the range 200 to 299, run these substeps:

    1. Let methods be the result of parsing all response's headers' named Access-Control-Allow-Methods.

    2. Let header names be the result of parsing all response's headers' named Access-Control-Allow-Headers.

    3. If either methods or header names is failure, change response into a network error and return it.

    4. 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.

    5. If request's method is not in methods and is not a simple method, return failure.

    6. If one of request's headers' names is not in header names or its corresponding header is not a simple header, change response into a network error and return it.

    7. Let max-age be the result of parsing all response's headers' named Access-Control-Max-Age.

    8. If max-age is failure, set max-age to zero.

    9. If max-age is greater than an imposed limit on max-age, set max-age to the imposed limit.

    10. If the user agent does not provide for a cache, return response.

    11. For each method in methods for which there is a method cache match using request, set matching entry's max-age to max-age.

    12. 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:

      origin
      request's origin
      url
      request's url
      max-age
      max-age
      credentials
      False if request's omit credentials flag is set, or true otherwise
      method
      method
    13. 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.

    14. 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:

      origin
      request's origin
      url
      request's url
      max-age
      max-age
      credentials
      False if request's omit credentials flag is set, or true otherwise
      header name
      header name
    15. Return response.

  12. Otherwise, if response is not an end-user abort, change response into a network error.

  13. Return response.

CORS preflight cache

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 flag is set or credentials is true and request's omit credentials flag is unset.

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.

CORS check

To perform a CORS check for a request and response, run these steps:

  1. If response's headers contains zero or more than one header whose name is Access-Control-Allow-Origin, return failure.

  2. Let result be the value of the header whose name is Access-Control-Allow-Origin within response's headers.

  3. If request's omit credentials flag is set and result is *, return success.

  4. If request's origin serialized to bytes is not result, return failure.

  5. If request's omit credentials flag is set, return success.

  6. If response's headers contains zero or more than one header whose name is Access-Control-Allow-Credentials, return failure.

  7. If the value of the header whose name is Access-Control-Allow-Origin within response's headers is true, return success.

  8. Return failure.