fetch README

The project's README from github.com/JakeChampion/fetch. As one markdown file: README.md.

window.fetch polyfill

OpenSSF Scorecard

The fetch() function is a Promise-based mechanism for programmatically making web requests in the browser. This project is a polyfill that implements a subset of the standard Fetch specification, enough to make fetch a viable replacement for most uses of XMLHttpRequest in traditional web applications.

Table of Contents

Read this first

Installation

npm install whatwg-fetch --save

You will also need a Promise polyfill for older browsers. We recommend taylorhakes/promise-polyfill for its small size and Promises/A+ compatibility.

Usage

Importing

Importing will automatically polyfill window.fetch and related APIs:

import 'whatwg-fetch'

window.fetch(...)

If for some reason you need to access the polyfill implementation, it is available via exports:

import {fetch as fetchPolyfill} from 'whatwg-fetch'

window.fetch(...)   // use native browser version
fetchPolyfill(...)  // use polyfill implementation

This approach can be used to, for example, use abort functionality in browsers that implement a native but outdated version of fetch that doesn't support aborting.

For use with webpack, add this package in the entry configuration option before your application entry point:

entry: ['whatwg-fetch', ...]

HTML

fetch('/users.html')
  .then(function(response) {
    return response.text()
  }).then(function(body) {
    document.body.innerHTML = body
  })

JSON

fetch('/users.json')
  .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) {
  console.log(response.headers.get('Content-Type'))
  console.log(response.headers.get('Date'))
  console.log(response.status)
  console.log(response.statusText)
})

Post form

var form = document.querySelector('form')

fetch('/users', {
  method: 'POST',
  body: new FormData(form)
})

Post JSON

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

File upload

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

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

fetch('/avatars', {
  method: 'POST',
  body: data
})

Caveats

Handling HTTP error statuses

To have fetch Promise reject on HTTP error statuses, i.e. on any non-2xx status, define a custom response handler:

function checkStatus(response) {
  if (response.status >= 200 && response.status < 300) {
    return response
  } else {
    var error = new Error(response.statusText)
    error.response = response
    throw error
  }
}

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

fetch('/users')
  .then(checkStatus)
  .then(parseJSON)
  .then(function(data) {
    console.log('request succeeded with JSON response', data)
  }).catch(function(error) {
    console.log('request failed', error)
  })

Sending cookies

For CORS requests, use credentials: 'include' to allow sending credentials to other domains:

fetch('https://example.com:1234/users', {
  credentials: 'include'
})

The default value for credentials is "same-origin".

The default for credentials wasn't always the same, though. The following versions of browsers implemented an older version of the fetch specification where the default was "omit":

If you target these browsers, it's advisable to always specify credentials: 'same-origin' explicitly with all fetch requests instead of relying on the default:

fetch('/users', {
  credentials: 'same-origin'
})

Note: due to limitations of XMLHttpRequest, using credentials: 'omit' is not respected for same domains in browsers where this polyfill is active. Cookies will always be sent to same domains in older browsers.

Receiving cookies

As with XMLHttpRequest, the Set-Cookie response header returned from the server is a forbidden header name and therefore can't be programmatically read with response.headers.get(). Instead, it's the browser's responsibility to handle new cookies being set (if applicable to the current URL). Unless they are HTTP-only, new cookies will be available through document.cookie.

Redirect modes

The Fetch specification defines these values for the redirect option: "follow" (the default), "error", and "manual".

Due to limitations of XMLHttpRequest, only the "follow" mode is available in browsers where this polyfill is active.

Obtaining the Response URL

Due to limitations of XMLHttpRequest, the response.url value might not be reliable after HTTP redirects on older browsers.

The solution is to configure the server to set the response HTTP header X-Request-URL to the current URL after any redirect that might have happened. It should be safe to set it unconditionally.

# Ruby on Rails controller example
response.headers['X-Request-URL'] = request.url

This server workaround is necessary if you need reliable response.url in Firefox < 32, Chrome < 37, Safari, or IE.

Aborting requests

This polyfill supports the abortable fetch API. However, aborting a fetch requires use of two additional DOM APIs: AbortController and AbortSignal. Typically, browsers that do not support fetch will also not support AbortController or AbortSignal. Consequently, you will need to include an additional polyfill for these APIs to abort fetches:

import 'yet-another-abortcontroller-polyfill'
import {fetch} from 'whatwg-fetch'

// use native browser implementation if it supports aborting
const abortableFetch = ('signal' in new Request('')) ? window.fetch : fetch

const controller = new AbortController()

abortableFetch('/avatars', {
  signal: controller.signal
}).catch(function(ex) {
  if (ex.name === 'AbortError') {
    console.log('request aborted')
  }
})

// some time later...
controller.abort()

Browser Support

Note: modern browsers such as Chrome, Firefox, Microsoft Edge, and Safari contain native implementations of window.fetch, therefore the code from this polyfill doesn't have any effect on those browsers. If you believe you've encountered an error with how window.fetch is implemented in any of these browsers, you should file an issue with that browser vendor instead of this project.

fetch (JakeChampion/fetch)

Searching Database…

25.8K ·GitHub
What is this?A window.fetch polyfill — a Promise-based mechanism for making web requests in the browser, giving older browsers the fetch API as a replacement for XMLHttpRequest.
Is it a library I bundle into my app, or a service I call?A client-side JavaScript library — a drop-in polyfill you bundle with your web app so code written against fetch also works in browsers that lack it natively.
How do I add it to a project?Install the package and import it before your application code — importing automatically polyfills window.fetch. With webpack, add it in the entry configuration option before your app's entry point.
Do I need anything else alongside it for older browsers?Yes — a Promise polyfill. The README recommends taylorhakes/promise-polyfill for its small size and Promises/A+ compatibility.
Does it implement the full fetch spec?No, a subset: redirect and cache directives are ignored, keepalive is unsupported, only the 'follow' redirect mode works, and Set-Cookie can't be read programmatically.
Which browsers does it actually cover?Chrome, Firefox, Safari 6.1+ and Internet Explorer 10+. In modern browsers that ship native fetch the code has no effect — it only kicks in where fetch is missing.
Can I use it on the server, say in Node.js?No — it's browser-only and doesn't work under Node.js, so make sure your application doesn't try to package and run it on the server.
Why doesn't the Promise reject when the server returns a 404 or 500?By design: the Promise fetch() returns resolves normally on HTTP error statuses and rejects only on network failure or if anything prevented the request from completing. To reject on any non-2xx status, define a custom response handler.
Can I abort a request once it's in flight?Yes — the polyfill supports the abortable fetch API, but aborting needs AbortController and AbortSignal, which browsers old enough to lack fetch usually lack too, so polyfill those as well. Alternatively, import the implementation via exports to use aborting even in browsers whose native fetch predates abort support.
How should I handle cookies so it works everywhere?Always supply credentials: 'same-origin' explicitly instead of relying on the default — Firefox 39-60, Chrome 42-67 and Safari 10.1-11.1.2 implemented an older spec where the default was 'omit'. Note that 'omit' isn't respected for same-domain requests where the polyfill is active: cookies are always sent to same domains.
My cross-domain request fails — is that a bug in the polyfill?No. CORS is exclusively handled by the browser's internal mechanisms, which the polyfill can't influence. The server must participate by implementing the right HTTP response headers, which is often nontrivial to set up or debug.
Size
0.6 MB
Stars
25.8K
Age
12y
Commits · 90 Days