The Fetch API provides a JavaScript interface for accessing and manipulating parts of the HTTP pipeline, such as requests and responses. It also provides a global fetch()
method that provides an easy, logical way to fetch resources asynchronously across the network.
This kind of functionality was previously achieved using XMLHttpRequest
. Fetch provides a better alternative that can be easily used by other technologies such as Service Workers
. Fetch also provides a single logical place to define other HTTP-related concepts such as CORS and extensions to HTTP.
The fetch
specification differs from jQuery.ajax()
in three main ways:
- The Promise returned from
fetch()
won’t reject on HTTP error status even if the response is an HTTP 404 or 500. Instead, it will resolve normally (withok
status set to false), and it will only reject on network failure or if anything prevented the request from completing. fetch()
can receive cross-site cookies; you can establish a cross site session using fetch.fetch
won’t send cookies, unless you set the credentials init option. (Since Aug 25, 2017. The spec changed the default credentials policy tosame-origin
. Firefox changed since 61.0b13.)
basic fetch
1 | fetch('http://example.com/movies.json') |
Supplying request options
1 | // Example POST method implementation: |
Uploading a file
1 | const formData = new FormData(); |
Uploading multiple files
1 | const formData = new FormData(); |
Processing a text file line by line
1 | async function* makeTextFileLineIterator(fileURL) { |
Checking that the fetch was successful
1 | fetch('flowers.jpg') |
Supplying your own request object
1 | const myHeaders = new Headers(); |
Request()
accepts exactly the same parameters as the fetch()
method. You can even pass in an existing request object to create a copy of it:
1 | const anotherRequest = new Request(myRequest, myInit); |
Headers
1 | const content = 'Hello World'; |
1 | fetch(myRequest) |
Guard
Since headers can be sent in requests and received in responses, and have various limitations about what information can and should be mutable, headers objects have a guard property. This is not exposed to the Web, but it affects which mutation operations are allowed on the headers object.
Possible guard values are:
none
: default.request
: guard for a headers object obtained from a request (Request.headers
).request-no-cors
: guard for a headers object obtained from a request created withRequest.mode
no-cors
.response
: guard for a Headers obtained from a response (Response.headers
).immutable
: Mostly used for ServiceWorkers; renders a headers object read-only.
Note: You may not append or set a request
guarded Headers’ Content-Length
header. Similarly, inserting Set-Cookie
into a response header is not allowed: ServiceWorkers are not allowed to set cookies via synthesized responses.
Response objects
As you have seen above, Response
instances are returned when fetch()
promises are resolved.
The most common response properties you’ll use are:
Response.status
— An integer (default value 200) containing the response status code.Response.statusText
— A string (default value “”), which corresponds to the HTTP status code message. Note that HTTP/2 does not support status messages.Response.ok
— seen in use above, this is a shorthand for checking that status is in the range 200-299 inclusive. This returns aBoolean
.
They can also be created programmatically via JavaScript, but this is only really useful in ServiceWorkers
, when you are providing a custom response to a received request using a respondWith()
method:
1 | const myBody = new Blob(); |
Body
Both requests and responses may contain body data. A body is an instance of any of the following types:
ArrayBuffer
ArrayBufferView
(Uint8Array and friends)Blob
/File- string
URLSearchParams
FormData
The Body
mixin defines the following methods to extract a body (implemented by both Request
and Response
). These all return a promise that is eventually resolved with the actual content.
This makes usage of non-textual data much easier than it was with XHR.
Request bodies can be set by passing body parameters:
1 | const form = new FormData(document.getElementById('login-form')); |
Feature detection
1 | if (window.fetch) { |