Fetch API
This lesson explains Fetch API with clear examples, use cases, and best practices so you can use HTML5 APIs confidently in real web applications.
HTML5 Fetch API Overview
The Fetch API is the modern JavaScript interface for making HTTP requests
from the browser. It replaces the older
XMLHttpRequest (XHR) API with a cleaner, Promise-based
interface that works naturally with async/await.
Developers use the Fetch API to retrieve data from REST APIs, submit
forms, upload files, download resources, authenticate users, communicate
with servers, and build modern Single Page Applications (SPAs).
| Feature | Description |
| API Name | Fetch API |
| Main Function | fetch() |
| Programming Style | Promise-based |
| Supports | GET, POST, PUT, PATCH, DELETE and more |
| Response Formats | JSON, Text, Blob, ArrayBuffer, FormData |
| Common Uses | REST APIs, authentication, uploads, downloads, data fetching |
Basic Fetch Syntax
// Basic Fetch request
fetch("/api/users")
.then((response) => response.json())
.then((users) => {
console.log(users);
})
.catch((error) => {
console.error(error);
});
The fetch() function returns a Promise that resolves to a
Response object. The response body can then be converted into
JSON, text, Blob, or other formats.
Fetch Request Lifecycle
| Step | Description |
| 1. Send Request | Browser sends an HTTP request using fetch(). |
| 2. Receive Response | Server returns an HTTP response. |
| 3. Check Status | Verify response.ok or response.status. |
| 4. Read Body | Convert response using json(), text(), or blob(). |
| 5. Handle Errors | Catch network or application errors. |
GET Request Example
// GET request using async/await
async function loadUsers() {
try {
const response =
await fetch("/api/users");
if (!response.ok) {
throw new Error("Unable to load users.");
}
const users =
await response.json();
console.log(users);
} catch (error) {
console.error(error.message);
}
}
loadUsers();
GET requests retrieve data from a server and are the most common Fetch API
operation.
POST Request Example
// POST request
async function createUser() {
const response =
await fetch("/api/users", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(
{
name: "John",
email: "john@example.com"
}
)
});
const result =
await response.json();
console.log(result);
}
createUser();
POST requests send data to the server, usually for creating new resources.
PUT Request Example
// Update existing resource
fetch("/api/users/5", {
method: "PUT",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(
{
name: "David"
}
)
})
.then((response) => response.json())
.then((data) => {
console.log(data);
});
DELETE Request Example
// Delete resource
fetch("/api/users/5", {
method: "DELETE"
})
.then((response) => {
console.log(response.status);
});
Common Fetch Options
| Option | Description | Example |
method | HTTP method. | GET, POST, PUT, DELETE |
headers | Request headers. | Content-Type, Authorization |
body | Request payload. | JSON.stringify(data) |
mode | CORS mode. | cors, no-cors, same-origin |
credentials | Cookie handling. | include, omit |
cache | Cache behavior. | default, reload, no-store |
signal | Abort request. | AbortController |
Response Methods
| Method | Returns | Common Use |
json() | JavaScript object | REST APIs |
text() | String | Plain text files |
blob() | Blob object | Images, PDFs |
arrayBuffer() | Binary data | Media processing |
formData() | FormData object | Forms and uploads |
Upload File Example
// Upload file
const formData =
new FormData();
formData.append(
"photo",
fileInput.files[0]
);
fetch("/upload", {
method: "POST",
body: formData
})
.then((response) => response.json())
.then((data) => {
console.log(data);
});
When sending FormData, do not manually set the
Content-Type header because the browser automatically adds
the correct multipart boundary.
Download File Example
// Download PDF
async function downloadFile() {
const response =
await fetch("/reports/monthly.pdf");
const blob =
await response.blob();
const url =
URL.createObjectURL(blob);
const link =
document.createElement("a");
link.href = url;
link.download = "report.pdf";
link.click();
URL.revokeObjectURL(url);
}
Cancel Request Example
// Abort Fetch request
const controller =
new AbortController();
fetch("/api/users", {
signal: controller.signal
});
setTimeout(() => {
controller.abort();
}, 3000);
AbortController lets you cancel slow or unnecessary requests,
improving performance and responsiveness.
Error Handling
try {
const response =
await fetch("/api/users");
if (!response.ok) {
throw new Error(
"HTTP Error: " +
response.status
);
}
const users =
await response.json();
console.log(users);
} catch (error) {
console.error(error.message);
}
Always check response.ok because Fetch only rejects Promises
for network failures, not HTTP errors such as 404 or 500.
Common HTTP Status Codes
| Status | Meaning |
| 200 | Success |
| 201 | Created |
| 204 | No Content |
| 400 | Bad Request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not Found |
| 500 | Internal Server Error |
Common Fetch API Use Cases
- REST API communication
- Loading dashboard data
- User authentication
- Submitting forms
- Uploading files
- Downloading documents
- Lazy loading content
- Progressive Web Apps
Fetch API Best Practices
- Always check
response.ok. - Wrap asynchronous code in
try...catch. - Use
async/await for readable code. - Abort unnecessary requests.
- Handle loading and error states in the UI.
- Use HTTPS for production APIs.
- Validate server responses before rendering.
- Reuse helper functions for API requests.
Common Fetch API Mistakes
- Assuming Fetch throws errors for HTTP 404 or 500 responses.
- Forgetting to await
response.json(). - Ignoring network failures.
- Not cancelling long-running requests.
- Sending JSON without the correct
Content-Type. - Setting multipart headers manually when using
FormData. - Ignoring CORS restrictions.
- Not handling authentication failures.
Fetch API vs XMLHttpRequest
| Feature | Fetch API | XMLHttpRequest |
| Programming Style | Promise-based | Callback/Event-based |
| async/await | Native support | Not supported |
| Readable Code | Excellent | Verbose |
| Abort Support | AbortController | abort() |
| Recommended Today | ✔ Yes | Legacy only |
Key Takeaways
- The Fetch API is the modern way to perform HTTP requests.
- It is Promise-based and works naturally with
async/await. - Support for GET, POST, PUT, PATCH, DELETE and other HTTP methods.
- Always check
response.ok before reading response data. - Supports uploads, downloads, authentication, and streaming responses.
- Use Fetch instead of XMLHttpRequest for new applications.
Pro Tip
Create a reusable API helper that automatically handles headers, JSON
parsing, authentication tokens, error handling, retries, and timeouts.
This keeps your application code clean and consistent.