fetch() API
Performs HTTP requests and returns a Promise of a Response object.
fetch(url, { method?, headers?, body? }).then(res => res.json())This static page keeps the syntax and examples indexed for search, while the coding app handles interactive exploration and saved references.
What it does
Overview
Performs HTTP requests and returns a Promise of a Response object.
The fetch() API provides a powerful, Promise-based interface for making asynchronous HTTP requests across the network. Unlike the older XMLHttpRequest, fetch() handles request and response objects in a more streamlined and modular fashion. A critical technical distinction is that a fetch() promise only rejects on network failures, DNS issues, or CORS violations; it does not reject on HTTP error statuses like 404 or 500. To handle these cases, developers must verify the 'ok' property or the 'status' code of the Response object. Performance-wise, fetch supports request cancellation via the AbortController API, which is essential for cleaning up side effects in modern UI frameworks. Additionally, the response body is a stream and can only be consumed once (using methods like .json(), .text(), or .blob()) before the stream is locked. Internet Explorer is not supported.
Quick reference
Syntax
fetch(url, { method?, headers?, body? }).then(res => res.json())
Inputs
Parameters
See it in practice
Examples
Standard GET Request with Error Handling
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(function(response) {
if (!response.ok) {
throw new Error('Network response was not ok: ' + response.status);
}
return response.json();
})
.then(function(data) {
console.log(data);
})
.catch(function(error) {
console.log('Fetch error: ' + error.message);
});{ userId: 1, id: 1, title: '...', body: '...' }
A basic GET request that manually checks the response.ok property to handle HTTP errors that do not trigger a promise rejection.
POST Request with JSON Body
fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
body: JSON.stringify({
title: 'New Post',
body: 'Content',
userId: 1
}),
headers: {
'Content-type': 'application/json; charset=UTF-8'
}
})
.then(function(response) { return response.json(); })
.then(function(json) { console.log(json); });{ title: 'New Post', body: 'Content', userId: 1, id: 101 }
Sending data to a server using the POST method. Requires stringifying the body and setting the appropriate Content-Type header.
Request Cancellation with AbortController
var controller = new AbortController();
var signal = controller.signal;
fetch('https://jsonplaceholder.typicode.com/photos', { signal: signal })
.then(function(res) { return res.json(); })
.catch(function(err) {
if (err.name === 'AbortError') {
console.log('Fetch request was cancelled');
} else {
console.log('Another error occurred');
}
});
// Cancel the request immediately for demonstration
controller.abort();Fetch request was cancelled
Using AbortController to terminate an ongoing fetch request. This is vital for performance and preventing memory leaks in components.
Debug faster
Common Errors
LogicError
Cause: Assuming that HTTP error codes like 404 or 500 will cause the promise to reject and trigger the .catch() block.
Fix: Always check response.ok or response.status inside the first .then() callback.
fetch('/invalid-url').catch(err => console.log('This will NOT run on a 404 error'))TypeError
Cause: Attempting to read the response body stream multiple times (e.g., calling .json() and then .text()).
Fix: The body can only be consumed once. Use .clone() if you need to read it multiple times, or store the result of the first read.
fetch(url).then(res => { res.json(); return res.text(); }) // Throws TypeError: body stream already readRuntime support
Compatibility
Source: MDN Web Docs
Common questions
Frequently Asked Questions
Performs HTTP requests and returns a Promise of a Response object.
url: Request URL. options: Method, headers, body, credentials, etc.
LogicError: Always check response.ok or response.status inside the first .then() callback. TypeError: The body can only be consumed once. Use .clone() if you need to read it multiple times, or store the result of the first read.