2014-10-13 03:26:22 +04:00
|
|
|
# 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.
|
|
|
|
|
|
|
|
## Installation
|
|
|
|
|
|
|
|
Available on [Bower](http://bower.io) as **fetch**.
|
|
|
|
|
2014-10-23 21:33:48 +04:00
|
|
|
```sh
|
2014-10-13 03:26:22 +04:00
|
|
|
$ bower install fetch
|
|
|
|
```
|
|
|
|
|
|
|
|
You'll also need a Promise polyfill for older browsers.
|
|
|
|
|
2014-10-23 21:33:48 +04:00
|
|
|
```sh
|
2014-10-31 03:29:06 +03:00
|
|
|
$ bower install es6-promise
|
2014-10-13 03:26:22 +04:00
|
|
|
```
|
|
|
|
|
2015-01-16 14:35:44 +03:00
|
|
|
This can also be installed with `npm`.
|
2014-10-23 20:44:34 +04:00
|
|
|
|
2014-10-23 21:33:48 +04:00
|
|
|
```sh
|
2015-01-10 02:24:56 +03:00
|
|
|
$ npm install whatwg-fetch --save
|
2014-10-23 20:44:34 +04:00
|
|
|
```
|
|
|
|
|
2015-01-27 22:17:23 +03:00
|
|
|
(For a node.js implementation, try [node-fetch](https://github.com/bitinn/node-fetch))
|
|
|
|
|
2014-10-13 03:26:22 +04:00
|
|
|
## Usage
|
|
|
|
|
|
|
|
The `fetch` function supports any HTTP method. We'll focus on GET and POST
|
|
|
|
example requests.
|
|
|
|
|
|
|
|
### HTML
|
|
|
|
|
|
|
|
```javascript
|
2014-10-14 19:57:48 +04:00
|
|
|
fetch('/users.html')
|
|
|
|
.then(function(response) {
|
|
|
|
return response.text()
|
|
|
|
}).then(function(body) {
|
|
|
|
document.body.innerHTML = body
|
|
|
|
})
|
2014-10-13 03:26:22 +04:00
|
|
|
```
|
|
|
|
|
|
|
|
### JSON
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
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
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
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
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
var form = document.querySelector('form')
|
|
|
|
|
|
|
|
fetch('/query', {
|
|
|
|
method: 'post',
|
|
|
|
body: new FormData(form)
|
|
|
|
})
|
|
|
|
```
|
|
|
|
|
|
|
|
### Post JSON
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
fetch('/users', {
|
|
|
|
method: 'post',
|
|
|
|
headers: {
|
|
|
|
'Accept': 'application/json',
|
|
|
|
'Content-Type': 'application/json'
|
|
|
|
},
|
|
|
|
body: JSON.stringify({
|
|
|
|
name: 'Hubot',
|
|
|
|
login: 'hubot',
|
|
|
|
})
|
|
|
|
})
|
|
|
|
```
|
|
|
|
|
|
|
|
### File upload
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
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
|
|
|
|
})
|
|
|
|
```
|
|
|
|
|
2014-10-20 11:47:11 +04:00
|
|
|
### Success and error handlers
|
|
|
|
|
2014-10-20 21:43:02 +04:00
|
|
|
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.
|
|
|
|
|
2014-10-20 11:47:11 +04:00
|
|
|
```javascript
|
2014-10-20 21:43:41 +04:00
|
|
|
function status(response) {
|
|
|
|
if (response.status >= 200 && response.status < 300) {
|
|
|
|
return Promise.resolve(response)
|
|
|
|
} else {
|
2014-11-21 02:26:41 +03:00
|
|
|
return Promise.reject(new Error(response.statusText))
|
2014-10-20 21:43:41 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function json(response) {
|
|
|
|
return response.json()
|
|
|
|
}
|
|
|
|
|
2014-10-20 11:47:11 +04:00
|
|
|
fetch('/users')
|
2014-10-20 21:43:41 +04:00
|
|
|
.then(status)
|
|
|
|
.then(json)
|
|
|
|
.then(function(json) {
|
|
|
|
console.log('request succeeded with json response', json)
|
2014-11-21 02:26:41 +03:00
|
|
|
}).catch(function(error) {
|
|
|
|
console.log('request failed', error)
|
2014-10-20 21:43:41 +04:00
|
|
|
})
|
2014-10-20 11:47:11 +04:00
|
|
|
```
|
|
|
|
|
2015-01-11 03:25:22 +03:00
|
|
|
### 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).
|
|
|
|
|
|
|
|
``` ruby
|
|
|
|
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.
|
|
|
|
|
2014-10-13 03:26:22 +04:00
|
|
|
## Browser Support
|
|
|
|
|
|
|
|
![Chrome](https://raw.github.com/alrra/browser-logos/master/chrome/chrome_48x48.png) | ![Firefox](https://raw.github.com/alrra/browser-logos/master/firefox/firefox_48x48.png) | ![IE](https://raw.github.com/alrra/browser-logos/master/internet-explorer/internet-explorer_48x48.png) | ![Opera](https://raw.github.com/alrra/browser-logos/master/opera/opera_48x48.png) | ![Safari](https://raw.github.com/alrra/browser-logos/master/safari/safari_48x48.png)
|
|
|
|
--- | --- | --- | --- | --- |
|
2015-01-16 00:14:37 +03:00
|
|
|
Latest ✔ | Latest ✔ | 9+ ✔ | Latest ✔ | 6.1+ ✔ |
|