Fetch Requests
Last updated
Last updated
Fetch requests are a way to send HTTP requests to a server directly from a page using JavaScript. The advantage of using fetch requests over, say, reloading the page are that
The contents of the page do not need to be reloaded each time the request is made
The request takes a little less time to get processed compared to sending server-to-server requests from the backend.
Allows content to be loaded "optionally" - content is not loaded on the page until it is specifically requested by the user, so pages have less content and are rendered faster.
Fetch requests follow this syntax:
resource
is the server (or resource) that the request is being sent to. It is a string with the URL.
options
contain some custom settings for the request. More details later
They return a - in other words, they return an asynchronous wrapper for the response from the server.
This promise can be processed using the .then
method, which takes in a unary function. This function is applied on the response recieved from the server.
The response from a fetch request is a JSON object with parameters like status
and protocol
and body
. Of these, the status
and body
parameters are the most useful for now.
200 OK
- all good
404 NOT FOUND
- the url/resource was not found on the server side
500 Internal Server Error
- the server ran into an error when trying to process the request
response.body
is an encoded object that contains the body of the response. Note that failed requests have null
as the value for the body
property for their response objects. To decode the body into readable JSON that can be processed by your JS code, use the method response.json()
.
You could imagine using the status
property in this way:
This status-checking and body-retrieval is often chained into 2 different promises using two sequential then
s:
Let's walk through it step by step:
fetch("somedomain.com/some-route/", someData)
- this line performs the fetch request and returns the response wrapped in a promise
.then(response => response.status === 200 ? response.json() : response.status)
- here, we check the response status code to see if the request was successful.
If the response was successful (i.e. response.status === 200
) then we return the body of the response using response.json()
If the response was not successful, we return the status code of the response so it can be shown to the user
.then(data => {...})
- this section of the code takes the data returned after processing the response
If the data returned is a number (i.e. typeof(data) === "number"
) then this means that the response status code was returned by the previous function, so there was an error, so we tell the user as such
Otherwise process the data as normal
Note that you may want to add more intermediary conditions and process different response codes differently, but the general form of a fetch request is as above.
Note that the fetch
function takes in two parameters: the resource
, and the options
.
options
is a JSON object that contains any custom settings that you may want to apply to the request. This includes header data, type of content being sent (if any), the content itself, and others. If any settings are ommitted, then the browser plugs in the default values for each setting. Below is an example of the options object, filled with default values for each setting (not all possible settings are shown).
Let's look at each setting:
headers
- this is a JSON object that contains the headers for the request. The sample shows two header settings:
body
- this setting specifies the body of the request (i.e. some data that needs to be processed by the resource server). Note that this must be a string; JSON.stringify
allows us to represent a JSON object with the request body as a string. Note also that a body
CANNOT be present for a GET
request.
Next, we'll write our own fetch request to the NUSMods API.
response.status
is an integer representing the HTTP Response Code returned by the server. The full list of response code can be found , but a few common ones are below:
method
- this setting specifies the request method. There are 4 commonly used methods(GET
, POST
, PUT
and DELETE
), and each are used in different situations. More details
mode
- what resource sharing mode should be allowed. "cors"
stands for "Cross-Origin Resource Sharing", and this mode allows sharing resources across origins. The other options are "no-cors"
and "same-origin"
. More details
cache
- how the request interacts with the browser's cache. Some different options are "no-cache", "no-store", "reload", and "only-if-cached". These options are explained
credentials
- this specifies whether or not the user should send/receive cookies from the resource. The two other options are "omit"
(never send/receive cookies) and "include"
(always send/receive cookies). More details
redirect
- this specifies how to handle if the resource redirects our request elsewhere. Some other options are "error"
and "manual"
. More details
"Content-Type"
- this header specifies the type of content being requested. It is in the format "type/subtype"
and some examples are "image/png"
(a png image), "text/plain"
(plain text), or "multipart/form-data"
(multiple parts of form data). The full list of options can be found .
"Access-Control-Allow-Origin"
- this header indicates whether the response can be shared with requesting code from the given origin. This could be "*"
, so all origins can have access to the response, or "<origin>"
where <origin>
is a domain/IP address. More details
There are many more headers that can be assigned, and they are all listed .
The are a very very useful resource for understanding HTTP requests and responses, as well as frontend web development with JavaScript.