1 |
|
2 | node-fetch
|
3 | ==========
|
4 |
|
5 | [![npm version][npm-image]][npm-url]
|
6 | [![build status][travis-image]][travis-url]
|
7 | [![coverage status][coveralls-image]][coveralls-url]
|
8 |
|
9 | A light-weight module that brings `window.fetch` to node.js & io.js
|
10 |
|
11 |
|
12 | # Motivation
|
13 |
|
14 | I really like the notion of Matt Andrews' [isomorphic-fetch](https://github.com/matthew-andrews/isomorphic-fetch): it bridges the API gap between client-side and server-side http requests, so developers have less to worry about.
|
15 |
|
16 | Instead of implementing `XMLHttpRequest` in node to run browser-specific [fetch polyfill](https://github.com/github/fetch), why not go from node's `http` to `fetch` API directly? Node has native stream support, browserify build targets (browsers) don't, so underneath they are going to be vastly different anyway.
|
17 |
|
18 | Hence `node-fetch`, minimal code for a `window.fetch` compatible API on node.js/io.js runtime.
|
19 |
|
20 |
|
21 | # Features
|
22 |
|
23 | - Stay consistent with `window.fetch` API.
|
24 | - 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.
|
25 | - Use native promise, but allow substituting it with [insert your favorite promise library].
|
26 | - Use native stream for body, on both request and response.
|
27 | - Decode content encoding (gzip/deflate) properly, and convert string output (such as `res.text()` and `res.json()`) to utf-8 automatically.
|
28 | - Useful extensions such as timeout, redirect limit, response size limit.
|
29 |
|
30 |
|
31 | # Difference from client-side fetch
|
32 |
|
33 | - See [Known Differences](https://github.com/bitinn/node-fetch/blob/master/LIMITS.md) for details.
|
34 | - If you happen to use a missing feature that `window.fetch` offers, feel free to open an issue.
|
35 | - Pull requests are welcomed too!
|
36 |
|
37 |
|
38 | # Install
|
39 |
|
40 | `npm install node-fetch --save`
|
41 |
|
42 |
|
43 | # Usage
|
44 |
|
45 | ```javascript
|
46 | var fetch = require('node-fetch');
|
47 |
|
48 | // If you are not on node v0.12, set a Promise library first, eg.
|
49 | // fetch.Promise = require('bluebird');
|
50 |
|
51 | // plain text or html
|
52 |
|
53 | fetch('https://github.com/')
|
54 | .then(function(res) {
|
55 | return res.text();
|
56 | }).then(function(body) {
|
57 | console.log(body);
|
58 | });
|
59 |
|
60 | // json
|
61 |
|
62 | fetch('https://api.github.com/users/github')
|
63 | .then(function(res) {
|
64 | return res.json();
|
65 | }).then(function(json) {
|
66 | console.log(json);
|
67 | });
|
68 |
|
69 | // meta
|
70 |
|
71 | fetch('https://github.com/')
|
72 | .then(function(res) {
|
73 | console.log(res.ok);
|
74 | console.log(res.status);
|
75 | console.log(res.statusText);
|
76 | console.log(res.headers.raw());
|
77 | console.log(res.headers.get('content-type'));
|
78 | });
|
79 |
|
80 | // post
|
81 |
|
82 | fetch('http://httpbin.org/post', { method: 'POST', body: 'a=1' })
|
83 | .then(function(res) {
|
84 | return res.json();
|
85 | }).then(function(json) {
|
86 | console.log(json);
|
87 | });
|
88 |
|
89 | // post with stream from resumer
|
90 |
|
91 | var resumer = require('resumer');
|
92 | var stream = resumer().queue('a=1').end();
|
93 | fetch('http://httpbin.org/post', { method: 'POST', body: stream })
|
94 | .then(function(res) {
|
95 | return res.json();
|
96 | }).then(function(json) {
|
97 | console.log(json);
|
98 | });
|
99 |
|
100 | // post with form-data
|
101 |
|
102 | var FormData = require('form-data');
|
103 | var form = new FormData();
|
104 | form.append('a', 1);
|
105 | fetch('http://httpbin.org/post', { method: 'POST', body: form, headers: form.getHeaders() })
|
106 | .then(function(res) {
|
107 | return res.json();
|
108 | }).then(function(json) {
|
109 | console.log(json);
|
110 | });
|
111 |
|
112 | // node 0.11+, yield with co
|
113 |
|
114 | var co = require('co');
|
115 | co(function *() {
|
116 | var res = yield fetch('https://api.github.com/users/github');
|
117 | var json = yield res.json();
|
118 | console.log(res);
|
119 | });
|
120 | ```
|
121 |
|
122 | See [test cases](https://github.com/bitinn/node-fetch/blob/master/test/test.js) for more examples.
|
123 |
|
124 |
|
125 | # API
|
126 |
|
127 | ## fetch(url, options)
|
128 |
|
129 | Returns a `Promise`
|
130 |
|
131 | ### Url
|
132 |
|
133 | Should be an absolute url, eg `http://example.com/`
|
134 |
|
135 | ### Options
|
136 |
|
137 | default values are shown, note that only `method`, `headers` and `body` are allowed in `window.fetch`, others are node.js extensions.
|
138 |
|
139 | ```
|
140 | {
|
141 | method: 'GET'
|
142 | , headers: {} // request header, format {a:1} or {b:[1,2,3]}
|
143 | , follow: 20 // maximum redirect count, 0 to not follow redirect
|
144 | , timeout: 0 // req/res timeout in ms, 0 to disable, timeout reset on redirect
|
145 | , compress: true // support gzip/deflate content encoding, false to disable
|
146 | , size: 0 // maximum response body size in bytes, 0 to disable
|
147 | , body: empty // request body, can be a string or readable stream
|
148 | , agent: null // custom http.Agent instance
|
149 | }
|
150 | ```
|
151 |
|
152 |
|
153 | # License
|
154 |
|
155 | MIT
|
156 |
|
157 |
|
158 | # Acknowledgement
|
159 |
|
160 | Thanks to [github/fetch](https://github.com/github/fetch) for providing a solid implementation reference.
|
161 |
|
162 |
|
163 | [npm-image]: https://img.shields.io/npm/v/node-fetch.svg?style=flat-square
|
164 | [npm-url]: https://www.npmjs.com/package/node-fetch
|
165 | [travis-image]: https://img.shields.io/travis/bitinn/node-fetch.svg?style=flat-square
|
166 | [travis-url]: https://travis-ci.org/bitinn/node-fetch
|
167 | [coveralls-image]: https://img.shields.io/coveralls/bitinn/node-fetch.svg?style=flat-square
|
168 | [coveralls-url]: https://coveralls.io/r/bitinn/node-fetch
|