Skip to content

fetch API ​

The WHATWG Fetch API with streaming support and chunked transfer decoding.

Globals ​

GlobalTypeDescription
fetch(input, init?)functionMakes HTTP requests, returns Promise<Response>
HeadersclassCase-insensitive HTTP header container
RequestclassHTTP request representation
ResponseclassHTTP response representation

fetch() ​

js
let response = await fetch('https://example.com/api/data', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ key: 'value' }),
    signal: controller.signal
});

Parameters ​

ParameterTypeDescription
inputstring | RequestURL or Request object
init.methodstringHTTP method (default: "GET")
init.headersHeaders | object | [string, string][]Request headers
init.bodystring | nullRequest body
init.signalAbortSignalAbort signal for cancellation

Response Object ​

js
let response = await fetch('https://example.com');

response.status;       // 200
response.statusText;   // "OK"
response.ok;           // true (status 200-299)
response.headers;      // Headers instance
response.url;          // request URL
response.type;         // "default", "error", "opaqueredirect"
response.body;         // ReadableStream or null
response.bodyUsed;     // false until consumed

// Consuming the body
let text = await response.text();
let json = await response.json();
let buffer = await response.arrayBuffer();

// Static methods
let errResponse = Response.error();
let redirect = Response.redirect('https://other.com', 302);
let jsonResponse = Response.json({ ok: true });

Headers ​

js
let headers = new Headers();
headers.set('Content-Type', 'application/json');
headers.append('Accept', 'text/html');
headers.get('Content-Type');    // "application/json"
headers.has('Content-Type');    // true
headers.delete('Accept');

// Iterate
for (let [name, value] of headers) {
    console.log(name, value);
}

// Construct from object
let h = new Headers({ 'X-Custom': 'value' });

// Construct from existing Headers
let copy = new Headers(h);

// Construct from array of pairs
let fromPairs = new Headers([['Content-Type', 'text/plain']]);

Streaming Responses ​

Response bodies are streamed via ReadableStream (when the transport supports streaming):

js
let response = await fetch('https://example.com/large-file');
let reader = response.body.getReader();

while (true) {
    let { done, value } = await reader.read();
    if (done) break;
    console.log('Received chunk:', value.length, 'bytes');
}

Aborting Requests ​

js
let controller = new AbortController();

// Abort after 5 seconds
setTimeout(() => controller.abort(), 5000);

try {
    let response = await fetch('https://slow-server.com', {
        signal: controller.signal
    });
} catch (err) {
    if (err.name === 'AbortError') {
        console.log('Request was aborted');
    }
}

Error Handling ​

js
try {
    let response = await fetch('https://invalid.url');
    if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
    }
    let data = await response.json();
} catch (err) {
    if (err instanceof TypeError) {
        console.error('Network error:', err.message);
    } else {
        console.error('Other error:', err);
    }
}

Notes ​

  • Only HTTP/HTTPS schemes are supported (no file://, data://)
  • Redirects are NOT automatically followed — the server's response is returned as-is
  • Headers.get(name) returns null only when the header is absent — a header present with an empty value returns ''
  • Request/Response constructors validate their inputs: method must be a valid HTTP token (non-empty, no whitespace), the URL must be absolute, and status must be an integer in 200–599 (Response.error() internally uses status 0)
  • request.arrayBuffer() / response.arrayBuffer() return a real ArrayBuffer; request.blob() / response.blob() return a Blob instance
  • Request bodies accept string, Uint8Array, ArrayBuffer, or ReadableStream (serialized to bytes for the transport)
  • Maximum header line length is 4096 bytes (implementation limit)

MIT Licensed