The Codex / JavaScript / Fetch API

Fetch API

Making HTTP requests from JavaScript — fetch(), Request, Response, Headers, streaming, and abort.

What it is, in plain English: The Fetch API is the modern way to make HTTP requests from JavaScript. fetch(url) returns a Promise that resolves to a Response object. You then call response.json(), response.text(), or response.blob() to read the body — these also return Promises. Fetch is available in all modern browsers and in Node.js from v18.

Making HTTP requests from the browser

Before fetch(), you needed XMLHttpRequest — verbose, callback-based, and painful. fetch() is clean, Promise-based, and works everywhere.

The simplest GET request

// fetch() returns a Promise → use await inside an async function
async function getUser() {
  const response = await fetch("https://api.example.com/user/1");

  // IMPORTANT: fetch() only rejects on network failure, not HTTP errors.
  // A 404 or 500 still "succeeds" — you must check response.ok:
  if (!response.ok) {
    throw new Error(`Failed: ${response.status}`);
  }

  const user = await response.json();  // parse the JSON body
  console.log(user.name);
}

getUser();

POST, PUT, DELETE — sending data

// POST with JSON body:
async function createPost(data) {
  const response = await fetch("https://api.example.com/posts", {
    method:  "POST",
    headers: { "Content-Type": "application/json" },
    body:    JSON.stringify(data),
  });
  return response.json();
}

// PUT — update a resource:
await fetch(`/api/users/${id}`, {
  method:  "PUT",
  headers: { "Content-Type": "application/json" },
  body:    JSON.stringify({ name: "Updated Name" }),
});

// DELETE:
await fetch(`/api/users/${id}`, { method: "DELETE" });

// With authentication header:
await fetch("/api/protected", {
  headers: {
    "Authorization": `Bearer ${token}`,
    "Content-Type": "application/json",
  },
});

Handling errors properly

async function apiFetch(url, options = {}) {
  try {
    const response = await fetch(url, options);

    if (!response.ok) {
      // Try to get error details from the response body:
      const error = await response.json().catch(() => ({}));
      throw new Error(error.message ?? `HTTP ${response.status}`);
    }

    return response.json();
  } catch (e) {
    if (e.name === "TypeError") {
      // Network error (offline, DNS failure, CORS blocked):
      throw new Error("Network error — check your connection");
    }
    throw e;
  }
}

// Usage:
try {
  const user = await apiFetch("/api/user/1");
  console.log(user.name);
} catch (e) {
  console.error(e.message);
}

Uploading files

// Use FormData — don't set Content-Type (browser sets it with boundary):
const form = document.querySelector("form");
const data = new FormData(form);

// Or build FormData manually:
const fd = new FormData();
fd.append("file", fileInput.files[0]);
fd.append("userId", "42");

const response = await fetch("/api/upload", {
  method: "POST",
  body:   fd,   // ← no Content-Type header! browser handles it
});
Try It Yourself

Official Sources

The Codex links only to official documentation and the ECMAScript specification. No third-party tutorials.