or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-whatwg-fetch

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

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/whatwg-fetch@3.6.x

To install, run

npx @tessl/cli install tessl/npm-whatwg-fetch@3.6.0

0

# whatwg-fetch

1

2

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.

3

4

## Package Information

5

6

- **Package Name**: whatwg-fetch

7

- **Package Type**: npm

8

- **Language**: JavaScript

9

- **Installation**: `npm install whatwg-fetch`

10

11

## Core Imports

12

13

```javascript

14

import 'whatwg-fetch'

15

16

// Global polyfill - automatically installs window.fetch and related APIs

17

// Only installs when native fetch is not available

18

window.fetch(...)

19

```

20

21

For explicit access to polyfill components:

22

23

```javascript

24

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

25

26

// Use polyfill explicitly alongside or instead of native

27

fetchPolyfill(...) // Always uses polyfill implementation

28

window.fetch(...) // Uses native browser version when available

29

```

30

31

CommonJS:

32

33

```javascript

34

require('whatwg-fetch');

35

36

// Global polyfill - automatically installs global.fetch, Headers, Request, Response

37

// Only installs when native fetch is not available

38

fetch(...)

39

```

40

41

## Basic Usage

42

43

```javascript

44

import 'whatwg-fetch'

45

46

// Simple GET request

47

fetch('/api/users')

48

.then(response => response.json())

49

.then(data => console.log(data))

50

.catch(error => console.error('Request failed:', error));

51

52

// POST with JSON data

53

fetch('/api/users', {

54

method: 'POST',

55

headers: {

56

'Content-Type': 'application/json'

57

},

58

body: JSON.stringify({

59

name: 'John Doe',

60

email: 'john@example.com'

61

})

62

})

63

.then(response => response.json())

64

.then(data => console.log('User created:', data));

65

66

// File upload with FormData

67

const formData = new FormData();

68

formData.append('file', fileInput.files[0]);

69

formData.append('description', 'Profile photo');

70

71

fetch('/upload', {

72

method: 'POST',

73

body: formData

74

})

75

.then(response => response.json());

76

```

77

78

## Architecture

79

80

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

81

82

- **Fetch Function**: Main entry point for HTTP requests with Promise-based interface

83

- **Request Class**: HTTP request representation with full configuration support

84

- **Response Class**: HTTP response representation with body parsing methods

85

- **Headers Class**: HTTP headers management with case-insensitive operations

86

- **Body Interface**: Shared body reading methods for Request and Response

87

- **Global Polyfill**: Automatic installation when native fetch is unavailable

88

89

## Capabilities

90

91

### HTTP Requests

92

93

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

94

95

```javascript { .api }

96

/**

97

* Make an HTTP request

98

* @param input - URL string, URL object, or Request object

99

* @param init - Optional request configuration

100

* @returns Promise that resolves to Response object

101

*/

102

function fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;

103

104

// Polyfill identification property

105

fetch.polyfill: boolean;

106

107

type RequestInfo = Request | string;

108

109

interface RequestInit {

110

method?: string;

111

headers?: HeadersInit;

112

body?: BodyInit;

113

credentials?: 'omit' | 'same-origin' | 'include';

114

mode?: string;

115

referrer?: string;

116

signal?: AbortSignal;

117

}

118

119

type ModeType = string;

120

121

type BodyInit = string | URLSearchParams | FormData | Blob | ArrayBuffer | ArrayBufferView | null;

122

type HeadersInit = Headers | Record<string, string> | [string, string][];

123

```

124

125

**Usage Examples:**

126

127

```javascript

128

// GET request

129

fetch('/api/data')

130

.then(response => {

131

if (!response.ok) {

132

throw new Error(`HTTP error! status: ${response.status}`);

133

}

134

return response.json();

135

});

136

137

// POST request with credentials

138

fetch('/api/login', {

139

method: 'POST',

140

credentials: 'include',

141

headers: {

142

'Content-Type': 'application/json'

143

},

144

body: JSON.stringify({ username, password })

145

});

146

147

// Request with abort signal

148

const controller = new AbortController();

149

fetch('/api/data', {

150

signal: controller.signal

151

});

152

153

// Cancel the request

154

controller.abort();

155

```

156

157

### Request Construction

158

159

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

160

161

```javascript { .api }

162

/**

163

* Create a new Request object

164

* @param input - URL string, URL object, or existing Request

165

* @param options - Request configuration options

166

*/

167

class Request {

168

constructor(input: RequestInfo, options?: RequestInit);

169

170

// Properties

171

readonly url: string;

172

readonly method: string;

173

readonly headers: Headers;

174

readonly credentials: 'omit' | 'same-origin' | 'include';

175

readonly mode: ModeType;

176

readonly signal: AbortSignal;

177

readonly referrer: string;

178

readonly bodyUsed: boolean;

179

180

// Methods

181

clone(): Request;

182

arrayBuffer(): Promise<ArrayBuffer>;

183

blob(): Promise<Blob>;

184

formData(): Promise<FormData>;

185

json(): Promise<any>;

186

text(): Promise<string>;

187

}

188

```

189

190

**Usage Examples:**

191

192

```javascript

193

// Create request with configuration

194

const request = new Request('/api/users', {

195

method: 'POST',

196

headers: {

197

'Content-Type': 'application/json',

198

'Authorization': 'Bearer token123'

199

},

200

body: JSON.stringify({ name: 'Alice' })

201

});

202

203

// Clone request for retry logic

204

const originalRequest = new Request('/api/data', { method: 'GET' });

205

const retryRequest = originalRequest.clone();

206

207

// Read request body

208

const requestData = await request.json();

209

```

210

211

### Response Handling

212

213

Handle HTTP responses with comprehensive body parsing and metadata access.

214

215

```javascript { .api }

216

/**

217

* HTTP Response representation

218

* @param bodyInit - Response body content

219

* @param options - Response configuration

220

*/

221

class Response {

222

constructor(bodyInit?: BodyInit, options?: ResponseInit);

223

224

// Properties

225

readonly url: string;

226

readonly status: number;

227

readonly statusText: string;

228

readonly ok: boolean;

229

readonly headers: Headers;

230

readonly type: 'default' | 'error';

231

readonly bodyUsed: boolean;

232

233

// Methods

234

clone(): Response;

235

arrayBuffer(): Promise<ArrayBuffer>;

236

blob(): Promise<Blob>;

237

formData(): Promise<FormData>;

238

json(): Promise<any>;

239

text(): Promise<string>;

240

241

// Static methods

242

static error(): Response;

243

static redirect(url: string, status?: number): Response;

244

}

245

246

interface ResponseInit {

247

status?: number;

248

statusText?: string;

249

headers?: HeadersInit;

250

url?: string;

251

}

252

```

253

254

**Usage Examples:**

255

256

```javascript

257

// Handle response with status checking

258

fetch('/api/data')

259

.then(response => {

260

console.log(`Status: ${response.status} ${response.statusText}`);

261

console.log(`Content-Type: ${response.headers.get('Content-Type')}`);

262

263

if (response.ok) {

264

return response.json();

265

} else {

266

throw new Error(`Request failed: ${response.status}`);

267

}

268

});

269

270

// Create custom responses

271

const successResponse = new Response(

272

JSON.stringify({ message: 'Success' }),

273

{

274

status: 200,

275

statusText: 'OK',

276

headers: { 'Content-Type': 'application/json' }

277

}

278

);

279

280

const errorResponse = Response.error();

281

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

282

```

283

284

### Headers Management

285

286

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

287

288

```javascript { .api }

289

/**

290

* HTTP headers collection

291

* @param init - Initial headers as object, array, or Headers instance

292

*/

293

class Headers {

294

constructor(init?: HeadersInit);

295

296

// Methods

297

append(name: string, value: string): void;

298

delete(name: string): void;

299

get(name: string): string | null;

300

has(name: string): boolean;

301

set(name: string, value: string): void;

302

forEach(callback: (value: string, name: string, headers: Headers) => void, thisArg?: any): void;

303

304

// Iterator methods

305

keys(): IterableIterator<string>;

306

values(): IterableIterator<string>;

307

entries(): IterableIterator<[string, string]>;

308

[Symbol.iterator](): IterableIterator<[string, string]>;

309

}

310

```

311

312

**Usage Examples:**

313

314

```javascript

315

// Create headers from object

316

const headers = new Headers({

317

'Content-Type': 'application/json',

318

'Authorization': 'Bearer token123'

319

});

320

321

// Add headers

322

headers.append('X-Custom-Header', 'value1');

323

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

324

325

// Check and get headers

326

if (headers.has('Content-Type')) {

327

console.log(headers.get('Content-Type')); // "application/json"

328

}

329

330

// Iterate over headers

331

headers.forEach((value, name) => {

332

console.log(`${name}: ${value}`);

333

});

334

335

// Use with fetch

336

fetch('/api/data', {

337

headers: new Headers({

338

'Accept': 'application/json',

339

'X-API-Key': 'key123'

340

})

341

});

342

```

343

344

### Error Handling

345

346

Handle fetch errors and request abortion with standard exception types.

347

348

```javascript { .api }

349

/**

350

* DOM Exception for fetch errors

351

* @param message - Error message

352

* @param name - Exception name (e.g., 'AbortError')

353

*/

354

class DOMException extends Error {

355

constructor(message?: string, name?: string);

356

357

readonly name: string;

358

readonly message: string;

359

readonly stack: string;

360

}

361

```

362

363

**Usage Examples:**

364

365

```javascript

366

// Handle different error types

367

const controller = new AbortController();

368

369

fetch('/api/data', { signal: controller.signal })

370

.then(response => response.json())

371

.catch(error => {

372

if (error.name === 'AbortError') {

373

console.log('Request was aborted');

374

} else if (error instanceof TypeError) {

375

console.log('Network error or request failed');

376

} else {

377

console.log('Other error:', error.message);

378

}

379

});

380

381

// Abort after timeout

382

setTimeout(() => controller.abort(), 5000);

383

384

// Check if polyfill is active

385

if (fetch.polyfill) {

386

console.log('Using whatwg-fetch polyfill');

387

} else {

388

console.log('Using native fetch implementation');

389

}

390

391

// Custom error handling for HTTP errors

392

function checkStatus(response) {

393

if (response.status >= 200 && response.status < 300) {

394

return response;

395

} else {

396

const error = new Error(response.statusText);

397

error.response = response;

398

throw error;

399

}

400

}

401

402

fetch('/api/data')

403

.then(checkStatus)

404

.then(response => response.json());

405

```

406

407

## Browser Compatibility

408

409

- **Chrome**: All versions

410

- **Firefox**: All versions

411

- **Safari**: 6.1+

412

- **Internet Explorer**: 10+

413

- **Modern Browsers**: Use native fetch when available

414

415

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

416

417

## Important Notes

418

419

- **Promise Rejection**: fetch() only rejects on network errors, not HTTP error status codes (404, 500, etc.)

420

- **Credentials**: Use `credentials: 'same-origin'` for maximum compatibility with cookies

421

- **CORS**: Cross-origin requests require proper server-side CORS configuration

422

- **Node.js**: This polyfill is browser-only and does not work in Node.js environments

423

- **AbortController**: Requires separate polyfill for browsers without native AbortController support

424

- **Polyfill Detection**: Check `fetch.polyfill` property to determine if polyfill is active

425

- **Automatic Installation**: The polyfill automatically detects native support and only activates when needed

426

- **Global Scope**: Importing the module automatically installs fetch, Headers, Request, Response globally

427

- **No-Cache Headers**: GET/HEAD requests with `cache: 'no-store'` or `cache: 'no-cache'` get timestamp parameters added

428

- **File Protocol**: Local file:// URLs receive status 200 even when xhr.status is outside normal range