The Fetch API
By Flavio Copes
Learn how to make HTTP requests with the Fetch API, check response errors, read response bodies, send JSON, set headers, and cancel a request.
- Introduction to the Fetch API
- Using Fetch
- Response Object
- Request Object
- Request headers
- POST Requests
- How to cancel a fetch request
Introduction to the Fetch API
The Fetch API is the standard way to make HTTP requests from JavaScript.
You call fetch(), and it returns a Promise that resolves to a Response object. You can then read the response as JSON, text, a blob, or another supported format.
Fetch is the modern replacement for XMLHttpRequest. It is available in browser windows and workers. You can find the complete API in the MDN Fetch reference.
Using Fetch
The simplest GET request looks like this:
fetch('/file.json')
This makes an HTTP request for file.json on the same origin.
Let’s read the response as JSON:
fetch('./file.json')
.then((response) => response.json())
.then((data) => console.log(data))
Calling fetch() returns a promise. The first callback receives a Response. The json() method reads its body and returns another Promise.
You can also use await:
async function getData() {
const response = await fetch('./file.json')
const data = await response.json()
console.log(data)
}
getData()
Catching errors
A Fetch Promise rejects for network failures and invalid requests. It does not reject just because the server returns 404 or 500.
Check response.ok before reading the body, as shown in the MDN Fetch error-handling guide:
async function getData() {
try {
const response = await fetch('./file.json')
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`)
}
const data = await response.json()
console.log(data)
} catch (error) {
console.error(error)
}
}
Response Object
The Response Object returned by a fetch() call contains all the information about the request and the response of the network request.
Metadata
headers
Accessing the headers property on the response object gives you the ability to look into the HTTP headers returned by the request:
fetch('./file.json').then((response) => {
console.log(response.headers.get('Content-Type'))
console.log(response.headers.get('Date'))
})

status
This property is the numeric HTTP response status, such as 200 or 404.
fetch('./file.json').then((response) => console.log(response.status))
statusText
statusText contains the status message returned by the server. Do not depend on it for application logic: HTTP/2 does not define status messages, so it can be empty. Use status or ok instead.
fetch('./file.json').then((response) => console.log(response.statusText))
url
url contains the final URL of the resource that was fetched.
fetch('./file.json').then((response) => console.log(response.url))
Body content
A response has a body, accessible using several methods:
text()returns the body as a stringjson()returns the body as a JSON-parsed objectblob()returns the body as a Blob objectformData()returns the body as a FormData objectarrayBuffer()returns the body as anArrayBufferobject
All those methods return a promise. Examples:
fetch('./file.json')
.then((response) => response.text())
.then((body) => console.log(body))
fetch('./file.json')
.then((response) => response.json())
.then((body) => console.log(body))

The same can be written using an async function:
async function getData() {
const response = await fetch('./file.json')
const data = await response.json()
console.log(data)
}
getData()
Request Object
The Request object represents a resource request, and it’s usually created using the new Request() API.
Example:
const req = new Request('/api/todos')
The Request object offers several read-only properties to inspect the request:
method: the request’s method (GET, POST, etc.)url: the URL of the requestheaders: the associated Headers object of the requestreferrer: the referrer of the requestcache: the cache mode of the request, such asdefault,reload, orno-cache
It also exposes methods including json(), text(), and formData() to read the request body.
The full API can be found at https://developer.mozilla.org/docs/Web/API/Request
Request headers
You can set request headers using a Headers object:
const headers = new Headers()
headers.append('Content-Type', 'application/json')
or:
const headers = new Headers({
'Content-Type': 'application/json',
})
To attach the headers to the request, we use the Request object, and pass it to fetch() instead of passing the URL.
Instead of:
fetch('./file.json')
we do
const request = new Request('./file.json', {
headers: new Headers({
'Content-Type': 'application/json',
}),
})
fetch(request)
You can also query it:
headers.has('Content-Type')
headers.get('Content-Type')
and we can delete a header that was previously set:
headers.delete('X-My-Custom-Header')
POST Requests
Fetch also supports other HTTP methods, including POST, PUT, PATCH, and DELETE.
Here is a JSON POST request:
async function createTodo() {
const response = await fetch('/api/todos', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
title: 'Learn the Fetch API',
}),
})
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`)
}
}
createTodo()
How to cancel a fetch request
You can cancel a request using AbortController.
Pass its signal to fetch():
const controller = new AbortController()
const signal = controller.signal
fetch('./file.json', { signal })
This cancels it after 5 seconds:
setTimeout(() => controller.abort(), 5 * 1000)
When the controller aborts, fetch() rejects with a DOMException named AbortError:
fetch('./file.json', { signal })
.then((response) => response.text())
.then((text) => console.log(text))
.catch((err) => {
if (err.name === 'AbortError') {
console.error('Fetch aborted')
} else {
console.error('Another error', err)
}
})Related posts about platform: