JavaScript Core/
Lesson

Making HTTPWhat is http?The protocol browsers and servers use to exchange web pages, API data, and other resources, defining how requests and responses are formatted. requests is the most common async task in web development. Whether you are loading user data, submitting a form, or calling a third-party APIWhat is api?A set of rules that lets one program talk to another, usually over the internet, by sending requests and getting responses., your application needs to talk to servers. The Fetch API is the modern, PromiseWhat is promise?An object that represents a value you don't have yet but will get in the future, letting your code keep running while it waits.-based way to do this. It replaced the older XMLHttpRequest with a cleaner interface that works naturally with async/awaitWhat is async/await?A syntax that lets you write asynchronous code (like fetching data) in a readable, step-by-step style instead of chaining callbacks..

Basic GET requests

The simplest fetch takes a URL and returns a PromiseWhat is promise?An object that represents a value you don't have yet but will get in the future, letting your code keep running while it waits.:

const response = await fetch('https://api.example.com/users');
const users = await response.json();
console.log(users);

Step by step: fetch() sends a GET request, returns a Promise that resolves to a Response object, then response.json() parses the body (also a Promise).

AI pitfall
AI tools frequently hardcode URLs directly in fetch calls and skip error handling entirely. A real application stores base URLs in configuration and always checks for non-200 responses. If Copilot generates fetch('https://api.example.com/users') with no error handling, you need to add response.ok checking and wrap it in try/catch before the code is production-ready.

The Response object

PropertyDescriptionExample
statusHTTP status code200, 404, 500
statusTextStatus message'OK', 'Not Found'
okBoolean for 200-299true / false
headersResponse headersHeaders object
urlFinal URL after redirects'https://...'
const response = await fetch('/api/users');

console.log(response.status);     // 200
console.log(response.ok);         // true
console.log(response.statusText); // 'OK'
Critical
Fetch only rejects on network failures (no internet, DNS error). A 404 or 500 response is a "successful" fetch, the Promise resolves. You must check response.ok yourself.
02

Parsing response bodies

MethodReturnsUse for
.json()Parsed JavaScript objectAPI responses (most common)
.text()Raw stringHTML, plain text
.blob()Binary blobImages, files
.formData()FormData objectForm responses
.arrayBuffer()ArrayBufferBinary manipulation

You can only read the body once. If you need it twice, clone the response first:

const response = await fetch('/api/data');
const clone = response.clone();

const text = await response.text();
const json = await clone.json();
03

POST and other request methods

Pass an options object as the second argument:

const newUser = { name: 'Alice', email: 'alice@example.com' };

const response = await fetch('https://api.example.com/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer token123'
  },
  body: JSON.stringify(newUser)
});

const created = await response.json();

Common HTTPWhat is http?The protocol browsers and servers use to exchange web pages, API data, and other resources, defining how requests and responses are formatted. methods

MethodUse caseBody?
GETRetrieve dataNo
POSTCreate new resourceYes
PUTReplace entire resourceYes
PATCHPartial updateYes
DELETERemove resourceOptional
04

Error handling pattern

This is the pattern you should use for every fetch call:

async function fetchUsers() {
  try {
    const response = await fetch('/api/users');

    if (!response.ok) {
      throw new Error(`HTTP ${response.status}: ${response.statusText}`);
    }

    return await response.json();
  } catch (error) {
    console.error('Failed to fetch users:', error.message);
    return [];
  }
}
05

Common fetch patterns

With query parameters:

const params = new URLSearchParams({
  page: '1',
  limit: '10',
  search: 'alice'
});

const response = await fetch(`/api/users?${params}`);

With authenticationWhat is authentication?Verifying who a user is, typically through credentials like a password or token.:

async function fetchWithAuth(url, options = {}) {
  const token = localStorage.getItem('token');

  return fetch(url, {
    ...options,
    headers: {
      ...options.headers,
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    }
  });
}

File upload:

const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('name', fileInput.files[0].name);

const response = await fetch('/api/upload', {
  method: 'POST',
  body: formData // Do NOT set Content-Type - fetch sets it automatically
});

06

Fetch vs other HTTPWhat is http?The protocol browsers and servers use to exchange web pages, API data, and other resources, defining how requests and responses are formatted. libraries

FeatureFetchAxios
Built-inYesNo (extra dependency)
Promise-basedYesYes
Automatic JSON parsingNo (manual .json())Yes
Request interceptorsNoYes
Request timeoutNo (use AbortController)Built-in
Browser supportModern browsersIE11+ with polyfill

For most applications, fetch is enough. Consider Axios if you need interceptors, automatic timeouts, or request cancellation.

07

Timeouts and cancellation

Fetch has no built-in timeout. Use AbortController or Promise.race():

// AbortController approach
const controller = new AbortController();
setTimeout(() => controller.abort(), 5000);

try {
  const response = await fetch('/api/data', {
    signal: controller.signal
  });
  const data = await response.json();
} catch (error) {
  if (error.name === 'AbortError') {
    console.log('Request timed out');
  }
}
08

Quick reference

PatternCode
Simple GETconst data = await (await fetch(url)).json()
POST with JSONfetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) })
Check statusif (!response.ok) throw new Error(...)
Query paramsfetch(\/api?${new URLSearchParams(params)}\)
Cancel requestfetch(url, { signal: controller.signal })
javascript
// GET request
const res = await fetch('https://api.example.com/users');
const users = await res.json();

// POST request
const res2 = await fetch('https://api.example.com/users', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ name: 'Alice' })
});