node-fetch/README.md

207 lines
6.1 KiB
Markdown
Raw Normal View History

2015-01-26 01:02:34 -08:00
node-fetch
==========
[![npm version][npm-image]][npm-url]
[![build status][travis-image]][travis-url]
2016-10-13 00:32:52 -07:00
[![coverage status][codecov-image]][codecov-url]
2015-01-26 01:02:34 -08:00
2016-04-05 10:32:37 -07:00
A light-weight module that brings `window.fetch` to Node.js
2015-01-26 01:02:34 -08:00
# Motivation
2016-08-03 03:02:26 -07:00
Instead of implementing `XMLHttpRequest` in Node.js to run browser-specific [Fetch polyfill](https://github.com/github/fetch), why not go from native `http` to `Fetch` API directly? Hence `node-fetch`, minimal code for a `window.fetch` compatible API on Node.js runtime.
2015-01-26 01:02:34 -08:00
2016-08-03 03:02:26 -07:00
See Matt Andrews' [isomorphic-fetch](https://github.com/matthew-andrews/isomorphic-fetch) for isomorphic usage (exports `node-fetch` for server-side, `whatwg-fetch` for client-side).
2015-01-26 01:02:34 -08:00
# Features
2015-01-26 05:28:23 -08:00
- Stay consistent with `window.fetch` API.
- Make conscious trade-off when following [whatwg fetch spec](https://fetch.spec.whatwg.org/) and [stream spec](https://streams.spec.whatwg.org/) implementation details, document known difference.
- Use native promise, but allow substituting it with [insert your favorite promise library].
2015-01-27 10:02:27 -08:00
- Use native stream for body, on both request and response.
2016-08-03 03:02:26 -07:00
- Decode content encoding (gzip/deflate) properly, and convert string output (such as `res.text()` and `res.json()`) to UTF-8 automatically.
2016-09-25 23:03:00 -07:00
- Useful extensions such as timeout, redirect limit, response size limit, [explicit errors](https://github.com/bitinn/node-fetch/blob/master/ERROR-HANDLING.md) for troubleshooting.
2015-01-26 05:28:23 -08:00
2015-01-27 05:11:26 -08:00
# Difference from client-side fetch
2015-01-26 05:28:23 -08:00
2015-05-03 03:07:20 -07:00
- See [Known Differences](https://github.com/bitinn/node-fetch/blob/master/LIMITS.md) for details.
2015-01-27 05:11:26 -08:00
- If you happen to use a missing feature that `window.fetch` offers, feel free to open an issue.
- Pull requests are welcomed too!
2015-01-26 01:02:34 -08:00
# Install
`npm install node-fetch --save`
# Usage
2015-01-27 09:20:54 -08:00
```javascript
2016-12-12 12:54:53 -08:00
import fetch from 'node-fetch';
// or
// const fetch = require('node-fetch');
2015-01-27 09:20:54 -08:00
2016-12-12 12:54:53 -08:00
// if you are using your own Promise library, set it through fetch.Promise. Eg.
// import Bluebird from 'bluebird';
// fetch.Promise = Bluebird;
2015-01-27 20:17:12 -08:00
2015-01-27 09:20:54 -08:00
// plain text or html
fetch('https://github.com/')
2016-12-12 12:54:53 -08:00
.then(res => res.text())
.then(body => console.log(body));
2015-01-27 09:20:54 -08:00
// json
fetch('https://api.github.com/users/github')
2016-12-12 12:54:53 -08:00
.then(res => res.json())
.then(json => console.log(json));
2015-01-27 09:20:54 -08:00
2016-09-24 02:21:40 -07:00
// catching network error
// 3xx-5xx responses are NOT network errors, and should be handled in then()
// you only need one catch() at the end of your promise chain
fetch('http://domain.invalid/')
2016-12-12 12:54:53 -08:00
.catch(err => console.error(err));
2016-09-24 02:21:40 -07:00
2016-08-16 05:22:18 -07:00
// stream
// the node.js way is to use stream when possible
2016-08-16 05:22:18 -07:00
fetch('https://assets-cdn.github.com/images/modules/logos_page/Octocat.png')
2016-12-12 12:54:53 -08:00
.then(res => {
const dest = fs.createWriteStream('./octocat.png');
res.body.pipe(dest);
2016-08-16 05:22:18 -07:00
});
// buffer
// if you prefer to cache binary data in full, use buffer()
// note that buffer() is a node-fetch only API
2016-12-12 12:54:53 -08:00
import fileType from 'file-type';
2016-08-16 05:22:18 -07:00
fetch('https://assets-cdn.github.com/images/modules/logos_page/Octocat.png')
2016-12-12 12:54:53 -08:00
.then(res => res.buffer())
.then(buffer => fileType(buffer))
.then(type => { /* ... */ });
2016-08-03 03:02:26 -07:00
2015-01-27 09:20:54 -08:00
// meta
fetch('https://github.com/')
2016-12-12 12:54:53 -08:00
.then(res => {
2015-01-27 20:17:12 -08:00
console.log(res.ok);
2015-01-27 09:20:54 -08:00
console.log(res.status);
console.log(res.statusText);
console.log(res.headers.raw());
console.log(res.headers.get('content-type'));
});
// post
2015-01-27 09:34:43 -08:00
fetch('http://httpbin.org/post', { method: 'POST', body: 'a=1' })
2016-12-12 12:54:53 -08:00
.then(res => res.json())
.then(json => console.log(json));
2015-01-27 09:20:54 -08:00
2016-12-12 12:54:53 -08:00
// post with stream from file
2015-01-27 09:20:54 -08:00
2016-12-12 12:54:53 -08:00
import { createReadStream } from 'fs';
const stream = createReadStream('input.txt');
2015-01-27 09:34:43 -08:00
fetch('http://httpbin.org/post', { method: 'POST', body: stream })
2016-12-12 12:54:53 -08:00
.then(res => res.json())
.then(json => console.log(json));
2015-01-27 09:20:54 -08:00
// post with JSON
var body = { a: 1 };
fetch('http://httpbin.org/post', {
method: 'POST',
body: JSON.stringify(body),
headers: { 'Content-Type': 'application/json' },
})
2016-12-12 12:54:53 -08:00
.then(res => res.json())
.then(json => console.log(json));
// post with form-data (detect multipart)
2015-01-27 09:20:54 -08:00
2016-12-12 12:54:53 -08:00
import FormData from 'form-data';
const form = new FormData();
2015-01-27 09:20:54 -08:00
form.append('a', 1);
fetch('http://httpbin.org/post', { method: 'POST', body: form })
2016-12-12 12:54:53 -08:00
.then(res => res.json())
.then(json => console.log(json));
2015-01-27 09:34:43 -08:00
// post with form-data (custom headers)
2016-08-16 05:22:18 -07:00
// note that getHeaders() is non-standard API
2016-12-12 12:54:53 -08:00
import FormData from 'form-data';
const form = new FormData();
form.append('a', 1);
fetch('http://httpbin.org/post', { method: 'POST', body: form, headers: form.getHeaders() })
2016-12-12 12:54:53 -08:00
.then(res => res.json())
.then(json => console.log(json));
2016-12-12 12:54:53 -08:00
// node 7+ with async function
2015-01-27 09:34:43 -08:00
2016-12-12 12:54:53 -08:00
(async function () {
const res = await fetch('https://api.github.com/users/github');
const json = await res.json();
console.log(json);
})();
2015-01-27 09:20:54 -08:00
```
See [test cases](https://github.com/bitinn/node-fetch/blob/master/test/test.js) for more examples.
2015-01-26 01:02:34 -08:00
2015-01-27 10:02:27 -08:00
# API
## fetch(url, options)
Returns a `Promise`
### Url
Should be an absolute url, eg `http://example.com/`
### Options
Note that only `method`, `headers`, `redirect` and `body` are allowed in `window.fetch`. Other options are node.js extensions. The default values are shown after each option key.
2015-01-27 10:02:27 -08:00
```
{
method: 'GET'
2016-04-05 12:25:16 -07:00
, headers: {} // request header. format {a:'1'} or {b:['1','2','3']}
2016-08-16 05:22:18 -07:00
, redirect: 'follow' // set to `manual` to extract redirect headers, `error` to reject redirect
2016-04-05 12:25:16 -07:00
, follow: 20 // maximum redirect count. 0 to not follow redirect
2016-08-16 05:22:18 -07:00
, timeout: 0 // req/res timeout in ms, it resets on redirect. 0 to disable (OS limit applies)
2016-04-05 12:25:16 -07:00
, compress: true // support gzip/deflate content encoding. false to disable
, size: 0 // maximum response body size in bytes. 0 to disable
, body: empty // request body. can be a string, buffer, readable stream
, agent: null // http.Agent instance, allows custom proxy, certificate etc.
2015-01-27 10:02:27 -08:00
}
```
2015-01-26 05:28:23 -08:00
# License
2015-01-26 01:02:34 -08:00
2015-01-26 05:28:23 -08:00
MIT
2015-01-26 01:02:34 -08:00
2015-01-26 05:28:23 -08:00
# Acknowledgement
2015-01-26 09:46:32 -08:00
Thanks to [github/fetch](https://github.com/github/fetch) for providing a solid implementation reference.
2015-01-26 01:02:34 -08:00
[npm-image]: https://img.shields.io/npm/v/node-fetch.svg?style=flat-square
[npm-url]: https://www.npmjs.com/package/node-fetch
[travis-image]: https://img.shields.io/travis/bitinn/node-fetch.svg?style=flat-square
[travis-url]: https://travis-ci.org/bitinn/node-fetch
2016-10-13 00:32:52 -07:00
[codecov-image]: https://img.shields.io/codecov/c/github/bitinn/node-fetch.svg?style=flat-square
[codecov-url]: https://codecov.io/gh/bitinn/node-fetch