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 的 polyfill —— 基于浏览器的 Promise 机制来发起网络请求,为老浏览器提供 fetch API,作为 XMLHttpRequest 的替代品。
它是打包进我应用的库,还是我调用的服务?一个客户端 JavaScript 库 —— 一个拿来即用的 polyfill,和你的网页应用一起打包,这样基于 fetch 写的代码在不原生支持 fetch 的浏览器里也能运行。
怎么把它加到项目里?安装这个包,并在你的应用代码之前导入 —— 导入后会自动为 window.fetch 打补丁。使用 webpack 时,把它加到 entry 配置项里,放在应用入口之前。
为了让老浏览器能用,我还需要别的依赖吗?需要 —— 还要一个 Promise polyfill。README 推荐使用 taylorhakes/promise-polyfill,因为它体积小,而且兼容 Promises/A+ 标准。
它实现了完整的 fetch 规范吗?没有,只实现了其中一部分:重定向和缓存相关的指令会被忽略,不支持 keepalive,重定向模式只有 'follow' 可用,而且无法在代码里读取 Set-Cookie。
它实际上支持哪些浏览器?Chrome、Firefox、Safari 6.1+ 和 Internet Explorer 10+。在原生自带 fetch 的现代浏览器里,这段代码不会起任何作用 —— 只在缺少 fetch 的浏览器里才会生效。
能在服务器端使用吗,比如在 Node.js 里?不能 —— 它只能在浏览器里运行,在 Node.js 下无法工作,所以请确保你的应用不会尝试把它打包后在服务器上运行。
为什么服务器返回 404 或 500 时 Promise 不进入 rejected 状态?这是设计如此:fetch() 返回的 Promise 在遇到 HTTP 错误状态码时仍会正常 resolve,只有在网络故障或请求因其他原因无法完成时才会 reject。想让任何非 2xx 状态码都触发 reject,需要自己定义一个响应处理函数。
请求发出之后还能取消吗?可以 —— 这个 polyfill 支持可中止的 fetch API,但中止请求需要 AbortController 和 AbortSignal,而老到缺少 fetch 的浏览器通常也缺少这两者,所以需要一并打补丁。另外,也可以通过 exports 导入它的实现,这样即使浏览器的原生 fetch 尚不支持中止操作,也能使用该功能。
cookie 应该怎么处理,才能在所有浏览器里都正常?始终显式指定 credentials: 'same-origin',不要依赖默认值 —— Firefox 39-60、Chrome 42-67 和 Safari 10.1-11.1.2 实现的是旧版规范,默认值是 'omit'。注意,在 polyfill 生效的情况下,'omit' 对同域请求并不起作用:发往同域的请求总会带上 cookie。
我的跨域请求失败了 —— 这是 polyfill 的 bug 吗?不是。CORS 完全由浏览器内部机制处理,polyfill 无法对其产生任何影响。服务器必须配合,返回正确的 HTTP 响应头才行,而这往往不好配置,也不好排查。
Size
0.6 MB
Stars
25.8K
Age
12y
Commits · 90 Days