UNPKG

6.29 kBMarkdownView Raw
1
2node-fetch
3==========
4
5[![npm version][npm-image]][npm-url]
6[![build status][travis-image]][travis-url]
7[![coverage status][codecov-image]][codecov-url]
8
9A light-weight module that brings `window.fetch` to Node.js
10
11
12# Motivation
13
14Instead 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.
15
16See 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).
17
18
19# Features
20
21- Stay consistent with `window.fetch` API.
22- 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.
23- Use native promise, but allow substituting it with [insert your favorite promise library].
24- Use native stream for body, on both request and response.
25- Decode content encoding (gzip/deflate) properly, and convert string output (such as `res.text()` and `res.json()`) to UTF-8 automatically.
26- 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.
27
28
29# Difference from client-side fetch
30
31- See [Known Differences](https://github.com/bitinn/node-fetch/blob/master/LIMITS.md) for details.
32- If you happen to use a missing feature that `window.fetch` offers, feel free to open an issue.
33- Pull requests are welcomed too!
34
35
36# Install
37
38`npm install node-fetch --save`
39
40
41# Usage
42
43```javascript
44import fetch from 'node-fetch';
45// or
46// const fetch = require('node-fetch');
47
48// if you are using your own Promise library, set it through fetch.Promise. Eg.
49
50// import Bluebird from 'bluebird';
51// fetch.Promise = Bluebird;
52
53// plain text or html
54
55fetch('https://github.com/')
56 .then(res => res.text())
57 .then(body => console.log(body));
58
59// json
60
61fetch('https://api.github.com/users/github')
62 .then(res => res.json())
63 .then(json => console.log(json));
64
65// catching network error
66// 3xx-5xx responses are NOT network errors, and should be handled in then()
67// you only need one catch() at the end of your promise chain
68
69fetch('http://domain.invalid/')
70 .catch(err => console.error(err));
71
72// stream
73// the node.js way is to use stream when possible
74
75fetch('https://assets-cdn.github.com/images/modules/logos_page/Octocat.png')
76 .then(res => {
77 const dest = fs.createWriteStream('./octocat.png');
78 res.body.pipe(dest);
79 });
80
81// buffer
82// if you prefer to cache binary data in full, use buffer()
83// note that buffer() is a node-fetch only API
84
85import fileType from 'file-type';
86
87fetch('https://assets-cdn.github.com/images/modules/logos_page/Octocat.png')
88 .then(res => res.buffer())
89 .then(buffer => fileType(buffer))
90 .then(type => { /* ... */ });
91
92// meta
93
94fetch('https://github.com/')
95 .then(res => {
96 console.log(res.ok);
97 console.log(res.status);
98 console.log(res.statusText);
99 console.log(res.headers.raw());
100 console.log(res.headers.get('content-type'));
101 });
102
103// post
104
105fetch('http://httpbin.org/post', { method: 'POST', body: 'a=1' })
106 .then(res => res.json())
107 .then(json => console.log(json));
108
109// post with stream from file
110
111import { createReadStream } from 'fs';
112
113const stream = createReadStream('input.txt');
114fetch('http://httpbin.org/post', { method: 'POST', body: stream })
115 .then(res => res.json())
116 .then(json => console.log(json));
117
118// post with JSON
119
120var body = { a: 1 };
121fetch('http://httpbin.org/post', {
122 method: 'POST',
123 body: JSON.stringify(body),
124 headers: { 'Content-Type': 'application/json' },
125})
126 .then(res => res.json())
127 .then(json => console.log(json));
128
129// post with form-data (detect multipart)
130
131import FormData from 'form-data';
132
133const form = new FormData();
134form.append('a', 1);
135fetch('http://httpbin.org/post', { method: 'POST', body: form })
136 .then(res => res.json())
137 .then(json => console.log(json));
138
139// post with form-data (custom headers)
140// note that getHeaders() is non-standard API
141
142import FormData from 'form-data';
143
144const form = new FormData();
145form.append('a', 1);
146fetch('http://httpbin.org/post', { method: 'POST', body: form, headers: form.getHeaders() })
147 .then(res => res.json())
148 .then(json => console.log(json));
149
150// node 7+ with async function
151
152(async function () {
153 const res = await fetch('https://api.github.com/users/github');
154 const json = await res.json();
155 console.log(json);
156})();
157```
158
159See [test cases](https://github.com/bitinn/node-fetch/blob/master/test/test.js) for more examples.
160
161
162# API
163
164## fetch(url, options)
165
166Returns a `Promise`
167
168### Url
169
170Should be an absolute url, eg `http://example.com/`
171
172### Options
173
174Note 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.
175
176```
177{
178 method: 'GET'
179 , headers: {} // request header. format {a:'1'} or {b:['1','2','3']}
180 , redirect: 'follow' // set to `manual` to extract redirect headers, `error` to reject redirect
181 , follow: 20 // maximum redirect count. 0 to not follow redirect
182 , timeout: 0 // req/res timeout in ms, it resets on redirect. 0 to disable (OS limit applies)
183 , compress: true // support gzip/deflate content encoding. false to disable
184 , size: 0 // maximum response body size in bytes. 0 to disable
185 , body: empty // request body. can be a string, buffer, readable stream
186 , agent: null // http.Agent instance, allows custom proxy, certificate etc.
187}
188```
189
190
191# License
192
193MIT
194
195
196# Acknowledgement
197
198Thanks to [github/fetch](https://github.com/github/fetch) for providing a solid implementation reference.
199
200
201[npm-image]: https://img.shields.io/npm/v/node-fetch.svg?style=flat-square
202[npm-url]: https://www.npmjs.com/package/node-fetch
203[travis-image]: https://img.shields.io/travis/bitinn/node-fetch.svg?style=flat-square
204[travis-url]: https://travis-ci.org/bitinn/node-fetch
205[codecov-image]: https://img.shields.io/codecov/c/github/bitinn/node-fetch.svg?style=flat-square
206[codecov-url]: https://codecov.io/gh/bitinn/node-fetch