CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-whatwg-fetch

A window.fetch polyfill for browsers that don't natively support the Fetch API

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

index.mddocs/

whatwg-fetch

whatwg-fetch is a comprehensive polyfill implementation of the Fetch API for web browsers that don't natively support window.fetch. It provides a Promise-based mechanism for making HTTP requests as a modern replacement for XMLHttpRequest, following the WHATWG Fetch specification standards.

Package Information

  • Package Name: whatwg-fetch
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install whatwg-fetch

Core Imports

import 'whatwg-fetch'

// Global polyfill - automatically installs window.fetch and related APIs
// Only installs when native fetch is not available
window.fetch(...)

For explicit access to polyfill components:

import { fetch as fetchPolyfill, Headers, Request, Response, DOMException } from 'whatwg-fetch'

// Use polyfill explicitly alongside or instead of native
fetchPolyfill(...) // Always uses polyfill implementation
window.fetch(...)   // Uses native browser version when available

CommonJS:

require('whatwg-fetch');

// Global polyfill - automatically installs global.fetch, Headers, Request, Response
// Only installs when native fetch is not available
fetch(...)

Basic Usage

import 'whatwg-fetch'

// Simple GET request
fetch('/api/users')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Request failed:', error));

// POST with JSON data
fetch('/api/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'John Doe',
    email: 'john@example.com'
  })
})
  .then(response => response.json())
  .then(data => console.log('User created:', data));

// File upload with FormData
const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('description', 'Profile photo');

fetch('/upload', {
  method: 'POST',
  body: formData
})
  .then(response => response.json());

Architecture

whatwg-fetch implements the complete Fetch API specification with these core components:

  • Fetch Function: Main entry point for HTTP requests with Promise-based interface
  • Request Class: HTTP request representation with full configuration support
  • Response Class: HTTP response representation with body parsing methods
  • Headers Class: HTTP headers management with case-insensitive operations
  • Body Interface: Shared body reading methods for Request and Response
  • Global Polyfill: Automatic installation when native fetch is unavailable

Capabilities

HTTP Requests

Core fetch functionality for making HTTP requests with full Promise support.

/**
 * Make an HTTP request
 * @param input - URL string, URL object, or Request object
 * @param init - Optional request configuration
 * @returns Promise that resolves to Response object
 */
function fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;

// Polyfill identification property
fetch.polyfill: boolean;

type RequestInfo = Request | string;

interface RequestInit {
  method?: string;
  headers?: HeadersInit;
  body?: BodyInit;
  credentials?: 'omit' | 'same-origin' | 'include';
  mode?: string;
  referrer?: string;
  signal?: AbortSignal;
}

type ModeType = string;

type BodyInit = string | URLSearchParams | FormData | Blob | ArrayBuffer | ArrayBufferView | null;
type HeadersInit = Headers | Record<string, string> | [string, string][];

Usage Examples:

// GET request
fetch('/api/data')
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return response.json();
  });

// POST request with credentials
fetch('/api/login', {
  method: 'POST',
  credentials: 'include',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ username, password })
});

// Request with abort signal
const controller = new AbortController();
fetch('/api/data', {
  signal: controller.signal
});

// Cancel the request
controller.abort();

Request Construction

Create and configure HTTP requests with full type safety and validation.

/**
 * Create a new Request object
 * @param input - URL string, URL object, or existing Request
 * @param options - Request configuration options
 */
class Request {
  constructor(input: RequestInfo, options?: RequestInit);
  
  // Properties
  readonly url: string;
  readonly method: string;
  readonly headers: Headers;
  readonly credentials: 'omit' | 'same-origin' | 'include';
  readonly mode: ModeType;
  readonly signal: AbortSignal;
  readonly referrer: string;
  readonly bodyUsed: boolean;
  
  // Methods
  clone(): Request;
  arrayBuffer(): Promise<ArrayBuffer>;
  blob(): Promise<Blob>;
  formData(): Promise<FormData>;
  json(): Promise<any>;
  text(): Promise<string>;
}

Usage Examples:

// Create request with configuration
const request = new Request('/api/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer token123'
  },
  body: JSON.stringify({ name: 'Alice' })
});

// Clone request for retry logic
const originalRequest = new Request('/api/data', { method: 'GET' });
const retryRequest = originalRequest.clone();

// Read request body
const requestData = await request.json();

Response Handling

Handle HTTP responses with comprehensive body parsing and metadata access.

/**
 * HTTP Response representation
 * @param bodyInit - Response body content
 * @param options - Response configuration
 */
class Response {
  constructor(bodyInit?: BodyInit, options?: ResponseInit);
  
  // Properties
  readonly url: string;
  readonly status: number;
  readonly statusText: string;
  readonly ok: boolean;
  readonly headers: Headers;
  readonly type: 'default' | 'error';
  readonly bodyUsed: boolean;
  
  // Methods
  clone(): Response;
  arrayBuffer(): Promise<ArrayBuffer>;
  blob(): Promise<Blob>;
  formData(): Promise<FormData>;
  json(): Promise<any>;
  text(): Promise<string>;
  
  // Static methods
  static error(): Response;
  static redirect(url: string, status?: number): Response;
}

interface ResponseInit {
  status?: number;
  statusText?: string;
  headers?: HeadersInit;
  url?: string;
}

Usage Examples:

// Handle response with status checking
fetch('/api/data')
  .then(response => {
    console.log(`Status: ${response.status} ${response.statusText}`);
    console.log(`Content-Type: ${response.headers.get('Content-Type')}`);
    
    if (response.ok) {
      return response.json();
    } else {
      throw new Error(`Request failed: ${response.status}`);
    }
  });

// Create custom responses
const successResponse = new Response(
  JSON.stringify({ message: 'Success' }),
  {
    status: 200,
    statusText: 'OK',
    headers: { 'Content-Type': 'application/json' }
  }
);

const errorResponse = Response.error();
const redirectResponse = Response.redirect('/login', 302);

Headers Management

Manage HTTP headers with case-insensitive operations and iteration support.

/**
 * HTTP headers collection
 * @param init - Initial headers as object, array, or Headers instance
 */
class Headers {
  constructor(init?: HeadersInit);
  
  // Methods
  append(name: string, value: string): void;
  delete(name: string): void;
  get(name: string): string | null;
  has(name: string): boolean;
  set(name: string, value: string): void;
  forEach(callback: (value: string, name: string, headers: Headers) => void, thisArg?: any): void;
  
  // Iterator methods
  keys(): IterableIterator<string>;
  values(): IterableIterator<string>;
  entries(): IterableIterator<[string, string]>;
  [Symbol.iterator](): IterableIterator<[string, string]>;
}

Usage Examples:

// Create headers from object
const headers = new Headers({
  'Content-Type': 'application/json',
  'Authorization': 'Bearer token123'
});

// Add headers
headers.append('X-Custom-Header', 'value1');
headers.append('X-Custom-Header', 'value2'); // Combines: "value1, value2"

// Check and get headers
if (headers.has('Content-Type')) {
  console.log(headers.get('Content-Type')); // "application/json"
}

// Iterate over headers
headers.forEach((value, name) => {
  console.log(`${name}: ${value}`);
});

// Use with fetch
fetch('/api/data', {
  headers: new Headers({
    'Accept': 'application/json',
    'X-API-Key': 'key123'
  })
});

Error Handling

Handle fetch errors and request abortion with standard exception types.

/**
 * DOM Exception for fetch errors
 * @param message - Error message
 * @param name - Exception name (e.g., 'AbortError')
 */
class DOMException extends Error {
  constructor(message?: string, name?: string);
  
  readonly name: string;
  readonly message: string;
  readonly stack: string;
}

Usage Examples:

// Handle different error types
const controller = new AbortController();

fetch('/api/data', { signal: controller.signal })
  .then(response => response.json())
  .catch(error => {
    if (error.name === 'AbortError') {
      console.log('Request was aborted');
    } else if (error instanceof TypeError) {
      console.log('Network error or request failed');
    } else {
      console.log('Other error:', error.message);
    }
  });

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

// Check if polyfill is active
if (fetch.polyfill) {
  console.log('Using whatwg-fetch polyfill');
} else {
  console.log('Using native fetch implementation');
}

// Custom error handling for HTTP errors
function checkStatus(response) {
  if (response.status >= 200 && response.status < 300) {
    return response;
  } else {
    const error = new Error(response.statusText);
    error.response = response;
    throw error;
  }
}

fetch('/api/data')
  .then(checkStatus)
  .then(response => response.json());

Browser Compatibility

  • Chrome: All versions
  • Firefox: All versions
  • Safari: 6.1+
  • Internet Explorer: 10+
  • Modern Browsers: Use native fetch when available

The polyfill automatically detects native fetch support and only installs itself when needed.

Important Notes

  • Promise Rejection: fetch() only rejects on network errors, not HTTP error status codes (404, 500, etc.)
  • Credentials: Use credentials: 'same-origin' for maximum compatibility with cookies
  • CORS: Cross-origin requests require proper server-side CORS configuration
  • Node.js: This polyfill is browser-only and does not work in Node.js environments
  • AbortController: Requires separate polyfill for browsers without native AbortController support
  • Polyfill Detection: Check fetch.polyfill property to determine if polyfill is active
  • Automatic Installation: The polyfill automatically detects native support and only activates when needed
  • Global Scope: Importing the module automatically installs fetch, Headers, Request, Response globally
  • No-Cache Headers: GET/HEAD requests with cache: 'no-store' or cache: 'no-cache' get timestamp parameters added
  • File Protocol: Local file:// URLs receive status 200 even when xhr.status is outside normal range

docs

index.md

tile.json