Chapter 4: Modern Networking with Fetch
The Fetch API is the modern standard for performing asynchronous network requests. This chapter provides a comprehensive technical reference for the fetch() function, the Request and Response interfaces, and advanced streaming patterns.
I. The fetch() API Reference
The fetch() method starts the process of fetching a resource from the network, returning a promise which resolves to the Response object representing the response to that request.
1. Function Syntax
const promise = fetch(resource [, options]);
2. Parameters
| Parameter | Type | Description |
|---|---|---|
resource | string | Request | URL | The URL of the resource or a Request object. |
options | Object (Optional) | An object containing custom settings for the request (see below). |
3. The options (RequestInit) Object
The options object allows for granular control over the HTTP request.
| Property | Type | Default | Description |
|---|---|---|---|
method | string | 'GET' | HTTP request method ('POST', 'PUT', 'DELETE', etc.). |
headers | Headers | Object | {} | Any headers to add to the request. |
body | string | Blob | FormData | URLSearchParams | null | The body of the request (not allowed for GET or HEAD). |
mode | string | 'cors' | The mode of the request ('cors', 'no-cors', 'same-origin'). |
credentials | string | 'same-origin' | Controls cookies ('omit', 'same-origin', 'include'). |
cache | string | 'default' | Cache mode ('default', 'no-store', 'reload', 'no-cache', 'force-cache'). |
redirect | string | 'follow' | How to handle redirects ('follow', 'error', 'manual'). |
referrer | string | 'about:client' | Referrer information for the request. |
integrity | string | "" | Subresource Integrity (SRI) value for security verification. |
keepalive | boolean | false | Allows the request to outlive the page. |
signal | AbortSignal | null | An instance of AbortSignal to cancel the request. |
II. The Response Object
When the fetch() promise resolves, it returns a Response instance.
1. Instance Properties (Read-only)
| Property | Type | Description |
|---|---|---|
ok | boolean | true if status is in the range 200–299. |
status | number | The HTTP status code (e.g., 200, 404). |
statusText | string | The status message (e.g., "OK", "Not Found"). |
headers | Headers | The Headers object associated with the response. |
url | string | The final URL of the response after any redirects. |
type | string | The type of the response ('basic', 'cors', 'error'). |
bodyUsed | boolean | true if the body has already been read. |
2. Body Consumption Methods
Every method returns a Promise that resolves with the parsed data. Note: The body can only be consumed once.
| Method | Return Type (Resolved) | Description |
|---|---|---|
.json() | any | Parses the body as a JSON object. |
.text() | string | Returns the body as a plain text string. |
.blob() | Blob | Returns the body as a binary Blob object. |
.arrayBuffer() | ArrayBuffer | Returns the body as a raw binary ArrayBuffer. |
.formData() | FormData | Parses the body as a FormData object. |
III. Error Handling & The AbortController
1. Network Errors vs. HTTP Errors
A critical distinction in fetch() is that HTTP error status codes (404, 500) do not cause the promise to reject.
- Promise Rejects: Only on network failure, DNS issues, or CORS violations.
- Promise Resolves: On any valid HTTP response (even
404).
// Production Standard Implementation
async function safeFetch(url) {
try {
const response = await fetch(url);
// Check for HTTP errors
if (!response.ok) {
throw new Error(`HTTP Error: ${response.status} ${response.statusText}`);
}
return await response.json();
} catch (error) {
// Catch network errors AND our manually thrown HTTP errors
console.error('Fetch failed:', error.message);
}
}
2. Request Cancellation (AbortController)
Use AbortController to implement timeouts or cancel requests when components unmount.
const controller = new AbortController();
const signal = controller.signal;
// Trigger cancellation after 3 seconds
const timeoutId = setTimeout(() => controller.abort(), 3000);
try {
const response = await fetch('/api/large-resource', { signal });
const data = await response.json();
} catch (err) {
if (err.name === 'AbortError') {
console.warn('Request was aborted');
} else {
console.error('Another error occurred:', err);
}
} finally {
clearTimeout(timeoutId);
}
IV. Advanced Patterns
1. HTTP/2 and Performance
Unlike HTTP/1.1, fetch() over HTTP/2 uses multiplexing. This allows multiple requests to be sent over a single TCP connection without "head-of-line blocking."
2. Response Cloning
If you need to read the body multiple times, use .clone().
const response = await fetch('/api/data');
const logClone = response.clone();
const data = await response.json(); // Consumes body
const raw = await logClone.text(); // Also works because of cloning
V. Core Engineering Standards
1. Security Mandates
- CORS Handling: Always wrap cross-origin requests in a
try/catchblock, as CORS failures result in aTypeError. - Sensitive Data: Never include API keys in the URL query string. Always prefer
Authorization: Bearer <token>in theheadersobject. - CSRF Protection: For state-changing requests (
POST,PUT,DELETE), ensure theX-Requested-With: XMLHttpRequestor a CSRF token header is present.
2. Performance Mandates
- Body Parsing: Never parse the body if the response is not
ok. This saves memory and prevents unexpected errors. - Keep-alive: Use
keepalive: truefor "fire and forget" tracking requests to ensure they finish even if the user closes the tab.