JavaScript Fetch API

Make HTTP requests from the browser and handle JSON responses

Overview

fetch is the modern browser API for network requests. It returns a Promise resolving to a Response object. Unlike older XHR, fetch does not reject on HTTP error status codes—you must check response.ok.

Syntax / Usage

// GET JSON
const response = await fetch('/api/users')
if (!response.ok) throw new Error(`HTTP ${response.status}`)
const users = await response.json()

// POST JSON
await fetch('/api/users', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ name: 'Ada' }),
})

// Other options
fetch(url, {
  method: 'PUT',
  headers: { Authorization: `Bearer ${token}` },
  signal: AbortSignal.timeout(5000),
})

Examples

Reusable API client:

async function api(path, options = {}) {
  const res = await fetch(`/api${path}`, {
    headers: { 'Content-Type': 'application/json', ...options.headers },
    ...options,
  })
  if (!res.ok) {
    const err = await res.json().catch(() => ({}))
    throw new Error(err.message || res.statusText)
  }
  return res.status === 204 ? null : res.json()
}

const user = await api('/users/1')

Cancel an in-flight request:

const controller = new AbortController()
fetch('/api/search?q=react', { signal: controller.signal })
// controller.abort() to cancel

Common Mistakes

  • Assuming non-2xx responses throw—they do not; check response.ok
  • Forgetting to stringify JSON bodies or set Content-Type
  • Not handling network errors separately from HTTP errors
  • Reading response.json() twice—the body stream can only be consumed once

See Also

promises async-await functions objects