fetch()
fetch(input[, init]) Returns:
Promise<Response> · Updated March 15, 2026 · Async APIs fetch http request async api
The fetch() function is the modern, Promise-based way to make HTTP requests in JavaScript. It replaces the older XMLHttpRequest API with a cleaner, more powerful interface built on top of Promises.
Unlike XMLHttpRequest, fetch() automatically rejects the Promise on network failure, making error handling more intuitive. However, it does not reject on HTTP error statuses (4xx, 5xx)—you must check response.ok manually.
Syntax
fetch(url)
fetch(url, options)
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
url | string or Request | — | The resource to fetch (URL string or Request object) |
init | RequestInit | undefined | Optional configuration object containing method, headers, body, etc. |
RequestInit Options
| Option | Type | Description |
|---|---|---|
method | string | HTTP method (GET, POST, PUT, DELETE, etc.). Default: GET |
headers | Headers or object | Request headers |
body | string or FormData or Blob or URLSearchParams | Request body (cannot be used with GET or HEAD) |
mode | string | CORS mode: “cors”, “no-cors”, or “same-origin” |
credentials | string | Include cookies: “omit”, “same-origin”, or “include” |
cache | string | Cache mode: “default”, “no-store”, “reload”, “no-cache”, “force-cache”, “only-if-cached” |
redirect | string | Follow, error, or manual redirect behavior |
signal | AbortSignal | AbortController signal to cancel the request |
referrer | string | Set the request’s Referer header |
referrerPolicy | string | Referrer policy |
Examples
Basic GET request
async function fetchUser() {
const response = await fetch('https://jsonplaceholder.typicode.com/users/1');
const data = await response.json();
console.log(data);
// { id: 1, name: "Leanne Graham", email: "Sincere@april.biz", ... }
}
fetchUser();
POST request with JSON body
async function createPost() {
const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
title: 'My New Post',
body: 'This is the post content.',
userId: 1
})
});
const data = await response.json();
console.log('Created:', data);
// Created: { title: "My New Post", body: "This is the post content.", userId: 1, id: 101 }
}
createPost();
Handling errors and checking response.ok
async function safeFetch(url) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('Fetch failed:', error.message);
throw error;
}
}
safeFetch('https://jsonplaceholder.typicode.com/posts/1');
// { userId: 1, id: 1, title: "...", body: "..." }
safeFetch('https://jsonplaceholder.typicode.com/nonexistent');
// Fetch failed: HTTP error! status: 404
Canceling a request with AbortController
async function fetchWithTimeout(url, timeoutMs = 5000) {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
try {
const response = await fetch(url, { signal: controller.signal });
return await response.json();
} finally {
clearTimeout(timeoutId);
}
}
fetchWithTimeout('https://jsonplaceholder.typicode.com/users/1', 1000)
.then(data => console.log(data))
.catch(err => console.error(err.name === 'AbortError' ? 'Request timed out' : err));
Sending cookies with credentials
async function fetchWithCookies(url) {
const response = await fetch(url, {
credentials: 'include',
headers: {
'Accept': 'application/json'
}
});
return response.json();
}
Common Patterns
JSON helper function:
async function fetchJSON(url, options = {}) {
const response = await fetch(url, {
...options,
headers: {
'Content-Type': 'application/json',
...options.headers
}
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return response.json();
}
const user = await fetchJSON('https://api.example.com/user/1');
Retry with exponential backoff:
async function fetchWithRetry(url, options = {}, retries = 3, delay = 1000) {
for (let i = 0; i < retries; i++) {
try {
const response = await fetch(url, options);
if (!response.ok && i < retries - 1) {
await new Promise(r => setTimeout(r, delay * Math.pow(2, i)));
continue;
}
return response;
} catch (err) {
if (i === retries - 1) throw err;
await new Promise(r => setTimeout(r, delay * Math.pow(2, i)));
}
}
}
Parallel requests with Promise.all:
async function fetchMultiple(urls) {
const requests = urls.map(url => fetch(url).then(r => r.json()));
return Promise.all(requests);
}
const [users, posts] = await fetchMultiple([
'https://jsonplaceholder.typicode.com/users',
'https://jsonplaceholder.typicode.com/posts'
]);
See Also
AbortController— Cancel fetch requestsPromise.all()— Wait for multiple promises to resolve