ReviseAlgo Logo

Browser APIs & Web APIs

Fetch API

Master network requests in JavaScript using the Fetch API. Learn custom headers, POST request structures, error handling, and AbortController integration.

Last Updated: July 15, 2026 12 min read

1. Introduction

The Fetch API is a modern, promise-based interface for making HTTP requests in the browser. It replaces the older, event-based XMLHttpRequest API, offering a cleaner syntax that integrates with Promises and async/await.

2. Why It Matters

Almost all web applications interact with backend APIs to fetch or save data. Mastering the Fetch API, including how to handle request headers, process JSON responses, check for HTTP errors, and cancel requests, is essential for frontend development.

3. Real-World Analogy

Think of ordering food from a Smart Room Service System:

  • GET Request (Menu check): You press a button on the smart screen (fetch API) to request the current menu. The screen fetches the data and displays it on your screen.
  • POST Request (Place Order): You select items, write delivery instructions (headers), add payment details (body payload), and submit the order.
  • AbortController (Cancel Order): You place the order. Five seconds later, you realize you selected the wrong items. You click "Cancel" before the kitchen starts cooking (triggering abort()), stopping the order.

4. Fetch Operations

Let's explore common Fetch API configurations:

1. GET Request:

By default, fetch() performs a GET request, returning a Promise that resolves to a Response object.

2. POST Request with Headers and JSON Body:

To send data, pass an options object as the second argument, specifying the method, headers, and body payload.

5. Fetch Error Handling Caveat

> [!IMPORTANT] > The Promise returned by fetch() does not reject on HTTP error status codes (like 404 or 500). The Promise only rejects on network failures or if the request is blocked. To detect HTTP errors, you must check the response.ok property (which is true for status codes in the 200-299 range) and handle failures manually.

6. Practical Example

This script demonstrates using an AbortController to cancel a fetch request if it takes too long:

7. Common Mistakes

  • Expecting fetch to reject on 500 status codes: Assumed network failure catch blocks will handle server crashes. You must check response.ok explicitly.
  • Trying to read the response body twice: Methods like response.json() or response.text() consume the response stream. Calling them a second time throws a TypeError: "body stream already read". If you need to read the body multiple times, clone the response first using response.clone().

8. Quick Quiz

Q1: Does a fetch() request reject when the server responds with a 404 Not Found error status?

A) Yes, all non-200 status codes reject

B) No, the promise resolves successfully; you must check response.ok manually

Answer: B — The fetch() promise only rejects on network failures. You must inspect response.ok to detect HTTP error statuses.

9. Scenario-Based Challenge

The Dynamic Request Multiplexer:

An application searches for records using a text input. If the user types a new character, cancel the previous search request if it is still running, and start a new request. Write a query function using AbortController to implement this cancellation logic.

10. Debugging Exercise

Explain why this POST request fails to send parameters to the server:

async function saveSettings(settings) {
  // Bug: content-type header missing, and body is not stringified!
  const response = await fetch('/api/settings', {
    method: 'POST',
    body: settings
  });
  return response.json();
}
saveSettings({ theme: 'dark' });
View Solution

Diagnosis: The body parameter must be a string, but a plain JavaScript object is passed instead. Additionally, the server does not know how to parse the payload because the Content-Type: application/json header is missing.

Fix: Stringify the body payload using JSON.stringify and set the Content-Type header:

const response = await fetch('/api/settings', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(settings) // Stringify payload
});

11. Interview Questions

🟢 Q1: Why does fetch not reject on 404 or 500 status codes, and how should you handle these errors?

Answer: The Fetch API models network communication. A 404 or 500 status code represents a successful HTTP transaction where the server received the request and returned a response, so the Promise resolves successfully. The Promise only rejects on network failures (like dns resolution failures or offline status). To handle HTTP errors, check the response.ok property, which is true only for status codes in the 200-299 range, and throw an error manually if it is false.

12. Production Considerations

  • Implement Timeouts: By default, fetch requests do not time out and can remain open indefinitely on slow connections. Always implement request timeouts using AbortController to prevent performance bottlenecks.