fetch() is an upgraded version of
XMLHttpRequest used to make
HTTP requests inside
The browser provides this object natively. This article describes its usage in detail.
1. Basic usage
The function of
fetch() is basically the same as
XMLHttpRequest, but with three main differences.
Promiseand does not use a callback function, so it is much simpler to write and more concise.
- The modular design of
APIspread over multiple objects (
Headersobject), is more reasonable; in contrast, the
XMLHttpRequestis not very good, with input, output and state all managed in the same interface, making it easy to write very confusing code.
fetch()processes data through a data stream (
Streamobject), which can be read in chunks, which is good for improving website performance and reducing memory usage, and is quite useful for requesting large files or slow internet scenarios. The
XMLHTTPRequestobject does not support data streams, all the data must be placed in the cache, does not support reading in chunks, you must wait until you get it all and then spit it out at once.
In terms of usage,
fetch() accepts a URL string as an argument, makes a
GET request to that URL by default, and returns a
Promise object. Its basic usage is as follows.
Here is an example to get
JSON data from the server.
In the above example, the
response received by
fetch() is a
Stream object, and
response.json() is an asynchronous operation that takes out all the content and converts it to a
Promise can be rewritten using the
await syntax to make the semantics clearer.
In the example above, the
await statement must be placed inside the
try.... .catch inside so as to catch any errors that may occur in the asynchronous operation.
The latter are written in the
await style, not in the
2. the Response object: handling HTTP responses
2.1 Synchronization Properties of Response Object
fetch() request succeeds, a Response object is obtained. It corresponds to the
HTTP response from the server.
As mentioned before,
Response contains data that is read asynchronously through the
Stream interface, but it also contains some synchronous properties that correspond to the header information (
Headers) of the
HTTP response, which can be read immediately.
In the above example,
response.statusText are the synchronization properties of
Response, which can be read immediately.
The header information attributes are as follows.
Response.ok property returns a boolean value indicating whether the request was successful or not,
true corresponding to the status codes
HTTP requests and false corresponding to the other status codes.
Response.status property returns a number indicating the status code of the
HTTP response (e.g.
200, for a successful request).
Response.statusText property returns a string indicating the status of the
HTTP response (for example, the server returns “OK” after a successful request).
Response.url property returns the
URL of the request. If there is a jump in the
URL, this property returns the final
URL. (return “OK”).
Response.type property returns the type of the request. The possible values are as follows.
basic: normal request, i.e. homologous request.
cors: cross-domain request.
error: network error, mainly used for
opaque: This value is returned if the
typeattribute of the
fetch()request is set to
no-cors, see the request section for details. Indicates that a simple cross-domain request is being made, similar to the kind of cross-domain request made by
opaqueredirect: This value is returned if the
redirectattribute of the
fetch()request is set to
manual, see the request section for details.
Response.redirected property returns a boolean value indicating whether the request has been redirected.
2.2 Determining whether a request is successful or not
fetch() issues a request, there is an important note:
fetch() will only report an error if there is a network error, or if the connection cannot be made, but in all other cases it will not report an error and will consider the request successful.
This means that
fetch() will not report an error even if the status code returned by the server is
Promise will not change to the
The only way to tell if a request is successful is to get the real status code of the
HTTP response through the
Response.status property. See the following example.
In the above example, the
response.status property is only equal to
2xx (200~299) to determine the success of the request. There is no need to consider URL bounces (with status code
fetch() will automatically turn the bounced status code to
Another way is to determine if
2.3 Response.headers property
Response object also has a
Response.headers property, which points to a
Headers object corresponding to all headers of the
The Headers object can be traversed using a for. . of loop to iterate through them.
Headers object provides the following methods to manipulate headers.
Headers.get(): Returns the key value, based on the specified key name.
Headers.has(): returns a boolean value indicating whether or not a header is contained.
Headers.set(): sets the specified key name to the new key value, or adds it if it does not exist.
Headers.append(): add the header.
Headers.delete(): delete the header.
Headers.keys(): return a traverser that iterates through all the key names in order.
Headers.values(): returns a traverser that iterates through all the key values in order.
Headers.entries(): returns a traverser that iterates through all key-value pairs ([key, value]) in order.
Headers.forEach(): iterates through the headers in turn, executing the argument function once for each header.
Some of the methods above can modify headers because they inherit from the
Headers interface. For
HTTP responses, it makes little sense to modify headers, and many headers are read-only, so browsers do not allow modifications.
The most common of these methods is
response.headers.get(), which is used to read the value of a header.
Headers.values() methods are used to iterate over the key names and key values of the headers, respectively.
Headers.forEach() method can also iterate through all the keys and key names.
2.4 Methods for reading content
Response object provides different read methods depending on the different types of data returned by the server.
response.text(): get the text string.
response.json(): get JSON object.
response.blob(): get the binary Blob object.
response.formData(): get the FormData form object.
response.arrayBuffer(): get the binary ArrayBuffer object.
5 read methods above are all asynchronous and return a
Promise object. You must wait until the asynchronous operation is finished to get the complete data returned by the server.
response.text() can be used to get text data, such as
response.json() is mainly used to get the
JSON data returned by the server, which has been given as an example earlier.
response.formData() is mainly used in the
Service Worker to intercept user-submitted forms, modify some data, and then submit them to the server.
response.blob() is used to get the binary file.
The above example reads the image file flower.jpg and displays it on the web page.
response.arrayBuffer() is mainly used to get the streaming file.
The above example is
response.arrayBuffer() to get the audio file song.ogg and then play it online.
Stream object can only be read once, and when it’s done, it’s gone. This means that only one of the five read methods in the previous section can be used, otherwise an error will be reported.
The above example uses
response.text() first, and then the
Stream is read out. If you call
response.json() later, there is no more content to read, so an error is reported.
Response object provides the
Response.clone() method to create a copy of the
Response object for multiple reads.
In the above example,
response.clone() makes a copy of the
Response object, and then reads the same image twice.
Response object also has a
Response.redirect() method that redirects the
Response result to the specified
URL. This method is generally only used inside the
Service Worker, so it is not described here.
2.6 The Response.body property
Response.body property is the underlying interface exposed by the
Response object, returning a
ReadableStream object for the user to manipulate.
It can be used to read content in chunks, and one application is to display the progress of a download.
In the above example, the
response.body.getReader() method returns a traverser. The
read() method of this traverser returns one object at a time, representing the block of content read this time.
done property of this object is a Boolean value that determines whether the read is complete; the
value property is an
arrayBuffer array that represents the contents of the block, and the
value.length property is the size of the current block.
3. the second parameter of fetch(): custom HTTP request
The first argument to
fetch() is the
URL, and it can also accept a second argument as a configuration object to customize the outgoing
optionObj of the above command is the second parameter.
The method, header, and data body of the HTTP request are set inside this object. Here are some examples.
In the above example, the configuration object uses three properties.
method: method of the HTTP request, POST, DELETE, PUT are set in this property.
headers: an object to customize the headers of the HTTP request.
body: the data body of the POST request.
Note that some headers cannot be set via the
headers attribute, such as
Host and so on. They are automatically generated by the browser and cannot be modified.
Submit JSON data
In the above example, the header
Content-Type should be set to ‘application/json;charset=utf-8’. Because the default sent is plain text, the default value of
Content-Type is ’text/plain;charset=UTF-8’.
If there is a file selector inside the form, you can use the previous example to write the uploaded file to be included in the whole form and submit it together.
Another way is to add files with a script to construct a form for uploading, see the example below.
When uploading binary files, you don’t need to change the
Content-Type in the header, the browser will set it automatically.
Upload binary data directly
fetch() can also upload binary data directly, putting
arrayBuffer data inside the
4. The full API for the fetch() configuration object
API for the second parameter of
fetch() is as follows.
fetch() request uses the interface of the
Request() object with exactly the same parameters, so the
API above is also the
Among these properties,
method have been given as examples earlier, and the following is an introduction to the other properties.
cache property specifies how the cache is handled. The possible values are as follows.
default: default value, look for matching requests inside the cache first.
no-store: request the remote server directly, and do not update the cache.
reload: request the remote server directly and update the cache.
no-cache: compare server resources with local cache, use server resources only if there is a new version, otherwise use cache.
force-cache: cache takes precedence and requests the remote server only if no cache exists.
only-if-cached: only check the cache, if it does not exist inside the cache, a 504 error will be returned.
mode attribute specifies the mode of the request. The possible values are as follows.
cors: default value, cross-domain requests are allowed.
same-origin: only same-origin requests are allowed.
no-cors: request methods are limited to
HEAD, and only a limited number of simple headers can be used, no cross-domain complex headers can be added, equivalent to the requests that can be made by submitting a form.
credentials attribute specifies whether to send
cookies. The possible values are as follows.
same-origin: default value, send
Cookiefor same-origin requests, not for cross-domain requests.
Cookieis sent for both same-origin and cross-domain requests.
omit: no cookie is sent for all requests.
Cross-domain requests send
Cookie and require the
credentials property to be set to
signal attribute specifies an
AbortSignal instance to cancel the
fetch() request, as detailed in the next section.
keepalive property is used when the page is offloaded to tell the browser to stay connected in the background and continue sending data.
A typical scenario is when a user leaves a web page and the script submits some statistics about the user’s behavior to the server. At this point, if the
keepalive property is not used, the data may not be sent because the browser has unloaded the page.
redirect attribute specifies the method of handling
HTTP jumps. The possible values are as follows.
follow: default value,
fetch()reports an error if a jump occurs.
fetch()does not follow HTTP jumps, but the
response.urlproperty will point to the new
response.redirectedproperty will change to
true, leaving it up to the developer to decide how to handle subsequent jumps.
integrity attribute specifies a hash value to check that the data returned by the
HTTP response is equal to this pre-defined hash value.
For example, when downloading a file, check that the
SHA-256 hash of the file matches to ensure that it has not been tampered with.
referrer attribute is used to set the
referer header for
This attribute can be any string, or it can be set to an empty string (i.e. no
referer header is sent).
referrerPolicy property is used to set the rules for the
Refererer header. The possible values are as follows.
no-referrer-when-downgrade: default, always sends the Referer header, unless it is not sent when requesting HTTP resources from HTTPS pages.
no-referrer: do not send the Referer header.
origin: The Referer header contains only the domain name, not the full path.
origin-when-cross-origin: same origin request Referer header contains full path, cross-domain request contains only domain name.
same-origin: cross-domain request does not send the Referer, same-origin request sends it.
strict-origin: The Referer header contains only the domain name, and the Referer header is not sent for HTTPS pages requesting HTTP resources.
strict-origin-when-cross-origin: The Referer header contains the full path for same-origin requests, and only the domain name for cross-domain requests; it is not sent when HTTPS pages request HTTP resources.
unsafe-url: always send the Referer header regardless of the case.
5. Cancel fetch() request
fetch() request is sent, if you want to cancel it in the middle, you need to use the
In the above example, first a new
AbortController instance is created, then a
fetch() request is sent, and the
signal property of the configuration object must specify to receive the signal
controller.signal from the
controller.abort() method is used to send the abort signal. This triggers the
abort event, which can be listened to, or the
controller.signal.aborted property can be used to determine if the cancel signal has been sent.
Here is an example of an automatic request cancellation after 1 second.
6. Reference Links
- Network requests: Fetch
- Introduction to fetch()
- Using Fetch