This exposes `fetch` as a CommonJS module. It's a light fork of [`whatwg-fetch`](https://www.npmjs.com/package/whatwg-fetch). I'll be trying to match their version numbers.

Usage no npm install needed!

<script type="module">
  import cjsFetch from 'https://cdn.skypack.dev/cjs-fetch';


fetch as a module

This exposes fetch as a CommonJS module. It's a light fork of whatwg-fetch. I'll be trying to match their version numbers.

The usage is either:

// Will use es6-promise by default
var fetch = require('cjs-fetch');

Or, with a different Promise implementation:

// use native promise or bluebird
var fetch = require('cjs-fetch/fetch')(
  typeof Promise !== 'undefined' ? Promise :

Original README:

window.fetch polyfill

The global fetch function is an easier way to make web requests and handle responses than using an XMLHttpRequest. This polyfill is written as closely as possible to the standard Fetch specification at https://fetch.spec.whatwg.org.


Available on Bower as fetch.

$ bower install fetch

You'll also need a Promise polyfill for older browsers.

$ bower install es6-promise

This can also be installed with npm.

$ npm install whatwg-fetch --save

(For a node.js implementation, try node-fetch)


The fetch function supports any HTTP method. We'll focus on GET and POST example requests.


  .then(function(response) {
    return response.text()
  }).then(function(body) {
    document.body.innerHTML = body


  .then(function(response) {
    return response.json()
  }).then(function(json) {
    console.log('parsed json', json)
  }).catch(function(ex) {
    console.log('parsing failed', ex)

Response metadata

fetch('/users.json').then(function(response) {

Post form

var form = document.querySelector('form')

fetch('/query', {
  method: 'post',
  body: new FormData(form)


fetch('/users', {
  method: 'post',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  body: JSON.stringify({
    name: 'Hubot',
    login: 'hubot',

File upload

var input = document.querySelector('input[type="file"]')

var form = new FormData()
form.append('file', input.files[0])
form.append('user', 'hubot')

fetch('/avatars', {
  method: 'post',
  body: form

Success and error handlers

This causes fetch to behave like jQuery's $.ajax by rejecting the Promise on HTTP failure status codes like 404, 500, etc. The response Promise is resolved only on successful, 200 level, status codes.

function status(response) {
  if (response.status >= 200 && response.status < 300) {
    return Promise.resolve(response)
  } else {
    return Promise.reject(new Error(response.statusText))

function json(response) {
  return response.json()

  .then(function(json) {
    console.log('request succeeded with json response', json)
  }).catch(function(error) {
    console.log('request failed', error)

Response URL caveat

The Response object has a URL attribute for the final responded resource. Usually this is the same as the Request url, but in the case of a redirect, its all transparent. Newer versions of XHR include a responseURL attribute that returns this value. But not every browser supports this. The compromise requires setting a special server side header to tell the browser what URL it just requested (yeah, I know browsers).

response.headers['X-Request-URL'] = request.url

If you want response.url to be reliable, you'll want to set this header. The day that you ditch this polyfill and use native fetch only, you can remove the header hack.

Browser Support

Chrome Firefox IE Opera Safari
Latest ✔ Latest ✔ 9+ ✔ Latest ✔ 6.1+ ✔