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
Что это такое?Полифилл для window.fetch — механизм для выполнения веб-запросов в браузере на основе Promise, который даёт старым браузерам fetch API как замену XMLHttpRequest.
Это библиотека, которую я подключаю в своё приложение, или сервис, к которому я обращаюсь?Клиентская JavaScript-библиотека — полифилл, который подключается «как есть» и собирается вместе с вашим веб-приложением, чтобы код, написанный под fetch, работал и в браузерах без встроенной поддержки fetch.
Как добавить его в проект?Установите пакет и импортируйте его до кода вашего приложения — при импорте автоматически добавляется полифилл для window.fetch. В webpack добавьте его в опцию конфигурации entry перед входной точкой вашего приложения.
Нужно ли что-то ещё вместе с ним для старых браузеров?Да — полифилл для Promise. В README рекомендуется taylorhakes/promise-polyfill благодаря небольшому размеру и совместимости с Promises/A+.
Он полностью реализует спецификацию fetch?Нет, только её часть: директивы redirect и cache игнорируются, keepalive не поддерживается, работает только режим перенаправления 'follow', а Set-Cookie нельзя прочитать программно.
Какие браузеры он на самом деле покрывает?Chrome, Firefox, Safari 6.1+ и Internet Explorer 10+. В современных браузерах со встроенным fetch код ничего не делает — он срабатывает только там, где fetch отсутствует.
Можно ли использовать его на сервере, например в Node.js?Нет — он работает только в браузере и не работает под Node.js, поэтому проследите, чтобы приложение не пыталось собрать и запустить его на сервере.
Почему Promise не переходит в состояние reject, когда сервер возвращает 404 или 500?Так задумано: Promise, который возвращает fetch(), успешно выполняется (resolves) при любых HTTP-ошибках и отклоняется (rejects) только при сбое сети или если что-то помешало завершить запрос. Чтобы отклонение срабатывало при любом статусе вне 2xx, определите собственный обработчик ответа.
Могу ли я отменить запрос, который уже выполняется?Да — полифилл поддерживает отменяемый fetch API, но для отмены нужны AbortController и AbortSignal, которых в браузерах, достаточно старых, чтобы в них не было fetch, тоже обычно нет, — так что добавьте полифиллы и для них. Либо импортируйте реализацию через exports, чтобы использовать отмену даже в браузерах, где встроенный fetch появился раньше поддержки отмены.
Как правильно работать с cookie, чтобы всё работало везде?Всегда указывайте credentials: 'same-origin' явно, а не полагайтесь на значение по умолчанию — в Firefox 39-60, Chrome 42-67 и Safari 10.1-11.1.2 реализована более старая спецификация, где по умолчанию было 'omit'. Учтите, что 'omit' не действует для запросов к тому же домену, когда активен полифилл: cookie всегда отправляются на те же домены.
Мой кросс-доменный запрос не работает — это баг полифилла?Нет. CORS обрабатывается исключительно внутренними механизмами браузера, на которые полифилл повлиять не может. Сервер должен отвечать нужными HTTP-заголовками, а их настроить или отладить зачастую непросто.
Size
0.6 MB
Stars
25.8K
Age
12y
Commits · 90 Days