Making HTTP Requests with the JavaScript Fetch API

The Fetch API replaced XMLHttpRequest as the standard way to make HTTP requests in JavaScript — promise-based, with a much cleaner API for the common cases.

async function getUser(id) {
    const response = await fetch(<code>/api/users/${id}</code>);

    if (!response.ok) {
        throw new Error(<code>HTTP ${response.status}</code>);
    }

    return response.json();
}

// POST with a JSON body
async function createUser(data) {
    const response = await fetch('/api/users', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data),
    });
    return response.json();
}

// Cancelling a request with AbortController
const controller = new AbortController();
setTimeout(() => controller.abort(), 5000); // cancel after 5s
fetch('/api/slow-endpoint', { signal: controller.signal });

The Gotcha: fetch Doesn’t Reject on HTTP Errors

A 404 or 500 response doesn’t throw automatically — fetch only rejects on network failures. You must check response.ok yourself, or your error handling silently misses actual HTTP errors entirely.