Technology · JavaScript
JavaScript Fetch API
Master the Fetch API for making HTTP requests in JavaScript, including GET, POST, error handling, and working with JSON responses.
- JavaScript Fetch API
- JavaScript Fetch API Guide
- JavaScript Fetch API Tips
- JavaScript Fetch API Tutorial
- JavaScript Fetch API Reference
- 01Use fetch() to make HTTP requests and always await the response before parsing it.
- 02Check response.ok before parsing — fetch only rejects on network failure, not HTTP errors.
- 03Use async/await with try/catch for clean, readable fetch code.
Basic GET Request
The Fetch API is the modern, promise-based way to make HTTP requests in JavaScript. It replaces older approaches like XMLHttpRequest.
async function getUser(id) {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
return response.json();
}
- fetch(url) returns a Promise that resolves to a
Responseobject. - response.ok is
truefor status codes 200–299. Always check it. - response.json() parses the body as JSON and returns another Promise.
- Fetch only rejects on network-level failures (no connection, DNS failure). A 404 or 500 does not reject — you must check
response.okyourself.
POST Request with JSON Body
Sending data requires setting the method, headers, and body in the options object.
async function createPost(data) {
const response = await fetch('/api/posts', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
});
if (!response.ok) throw new Error('Request failed');
return response.json();
}
| Option | Purpose | Example |
|---|---|---|
method |
HTTP verb | 'POST', 'PUT', 'DELETE' |
headers |
Request headers | { 'Content-Type': 'application/json' } |
body |
Request payload | JSON.stringify(data) |
credentials |
Send cookies | 'include' or 'same-origin' |
Error Handling Patterns
Robust fetch code handles both network errors and HTTP error responses.
async function safeFetch(url, options = {}) {
try {
const res = await fetch(url, options);
if (!res.ok) {
const msg = await res.text();
throw new Error(`${res.status}: ${msg}`);
}
return await res.json();
} catch (err) {
console.error('Fetch failed:', err);
throw err;
}
}
- Wrap
fetchin try/catch to catch network-level errors (offline, CORS, DNS). - Check response.ok inside the try block to catch HTTP errors (4xx, 5xx).
- Read
res.text()orres.json()on error responses to get the server's error message.
Warning: Calling
response.json()on an error response that returns HTML (like a 404 page) will throw a JSON parse error. Useres.text()as a safe fallback when the content type is unknown.
Common Fetch Patterns
These patterns cover the most frequent real-world fetch use cases.
| Pattern | Code |
|---|---|
| Send auth token | headers: { Authorization: 'Bearer ' + token } |
| Send form data | body: new FormData(formEl) (no Content-Type header needed) |
| Abort a request | const ac = new AbortController(); fetch(url, { signal: ac.signal }) |
| Read plain text | const text = await response.text() |
| Download a blob | const blob = await response.blob() |
Use AbortController to cancel in-flight requests — useful in React useEffect cleanup to prevent state updates on unmounted components.
Fetch vs Alternatives
Know when to reach for a library versus the native Fetch API.
| Tool | Best For | Trade-off |
|---|---|---|
| fetch() | Simple requests, no extra dependencies | Verbose error handling, no interceptors |
| axios | Complex apps needing interceptors, retries | External dependency (~15 kB gzipped) |
| SWR / React Query | Data fetching in React with caching | Framework-specific, more setup |
| tRPC | Full-stack TypeScript with end-to-end types | Requires matching server setup |
Tip: For Next.js App Router, prefer the built-in
fetchextended by Next.js — it supportscacheandnext.revalidateoptions directly, enabling server-side data fetching with ISR.