fetch() is an upgraded version of XMLHttpRequest used to make HTTP requests inside JavaScript scripts.
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.
fetch()usesPromiseand does not use a callback function, so it is much simpler to write and more concise.- The modular design of
fetch(), withAPIspread over multiple objects (Responseobject,Requestobject,Headersobject), is more reasonable; in contrast, theAPIdesign ofXMLHttpRequestis 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. TheXMLHTTPRequestobject 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 JSON object.
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 .then() style.
2. the Response object: handling HTTP responses
2.1 Synchronization Properties of Response Object
When a 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.status and response.statusText are the synchronization properties of Response, which can be read immediately.
The header information attributes are as follows.
Response.ok
The Response.ok property returns a boolean value indicating whether the request was successful or not, true corresponding to the status codes 200 to 299 for HTTP requests and false corresponding to the other status codes.
Response.status
The Response.status property returns a number indicating the status code of the HTTP response (e.g. 200, for a successful request).
Response.statusText
The 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
The 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
The 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 forService Worker.opaque: This value is returned if thetypeattribute of thefetch()request is set tono-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<form>forms.opaqueredirect: This value is returned if theredirectattribute of thefetch()request is set tomanual, see the request section for details.
Response.redirected
The Response.redirected property returns a boolean value indicating whether the request has been redirected.
2.2 Determining whether a request is successful or not
After 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 4xx or 5xx (i.e. Promise will not change to the rejected state).
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 3xx), because fetch() will automatically turn the bounced status code to 200.
Another way is to determine if response.ok is true.
2.3 Response.headers property
The Response object also has a Response.headers property, which points to a Headers object corresponding to all headers of the HTTP response.
The Headers object can be traversed using a for. . of loop to iterate through them.
The 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.
The Headers.keys() and Headers.values() methods are used to iterate over the key names and key values of the headers, respectively.
The Headers.forEach() method can also iterate through all the keys and key names.
2.4 Methods for reading content
The 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.
The 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()
response.text() can be used to get text data, such as HTML files.
response.json()
response.json() is mainly used to get the JSON data returned by the server, which has been given as an example earlier.
response.formData()
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()
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()
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.
2.5 Response.clone()
The 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.
The 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.
The 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
The 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.
The 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 HTTP request.
|
|
The 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.
POST request
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 Content-Length, Cookie, 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’.
Submission Form
File upload
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 Blob or arrayBuffer data inside the body property.
4. The full API for the fetch() configuration object
The full API for the second parameter of fetch() is as follows.
|
|
The underlying fetch() request uses the interface of the Request() object with exactly the same parameters, so the API above is also the API of Request().
Among these properties, headers, body, and method have been given as examples earlier, and the following is an introduction to the other properties.
cache
The 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
The 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 toGET,POSTandHEAD, 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
The credentials attribute specifies whether to send cookies. The possible values are as follows.
same-origin: default value, sendCookiefor same-origin requests, not for cross-domain requests.include: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 include.
signal
The signal attribute specifies an AbortSignal instance to cancel the fetch() request, as detailed in the next section.
keepalive
The 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
The redirect attribute specifies the method of handling HTTP jumps. The possible values are as follows.
follow: default value,fetch()followsHTTPjumps.error:fetch()reports an error if a jump occurs.manual:fetch()does not follow HTTP jumps, but theresponse.urlproperty will point to the newURLand theresponse.redirectedproperty will change totrue, leaving it up to the developer to decide how to handle subsequent jumps.
integrity
The 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
The referrer attribute is used to set the referer header for fetch() requests.
This attribute can be any string, or it can be set to an empty string (i.e. no referer header is sent).
referrerPolicy
The 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
After the fetch() request is sent, if you want to cancel it in the middle, you need to use the AbortController object.
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 AbortController instance.
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
- node-fetch
- Introduction to fetch()
- Using Fetch
- Javascript Fetch API: The XMLHttpRequest evolution
Reference https://www.ruanyifeng.com/blog/2020/12/fetch-tutorial.html