Simple email application for Android. Original source code: https://framagit.org/dystopia-project/simple-email
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

489 lines
16 KiB

  1. node-fetch
  2. ==========
  3. [![npm version][npm-image]][npm-url]
  4. [![build status][travis-image]][travis-url]
  5. [![coverage status][codecov-image]][codecov-url]
  6. [![install size][install-size-image]][install-size-url]
  7. A light-weight module that brings `window.fetch` to Node.js
  8. (We are looking for [v2 maintainers and collaborators](https://github.com/bitinn/node-fetch/issues/252))
  9. <!-- TOC -->
  10. - [Motivation](#motivation)
  11. - [Features](#features)
  12. - [Difference from client-side fetch](#difference-from-client-side-fetch)
  13. - [Installation](#installation)
  14. - [Loading and configuring the module](#loading-and-configuring-the-module)
  15. - [Common Usage](#common-usage)
  16. - [Plain text or HTML](#plain-text-or-html)
  17. - [JSON](#json)
  18. - [Simple Post](#simple-post)
  19. - [Post with JSON](#post-with-json)
  20. - [Post with form parameters](#post-with-form-parameters)
  21. - [Handling exceptions](#handling-exceptions)
  22. - [Handling client and server errors](#handling-client-and-server-errors)
  23. - [Advanced Usage](#advanced-usage)
  24. - [Streams](#streams)
  25. - [Buffer](#buffer)
  26. - [Accessing Headers and other Meta data](#accessing-headers-and-other-meta-data)
  27. - [Post data using a file stream](#post-data-using-a-file-stream)
  28. - [Post with form-data (detect multipart)](#post-with-form-data-detect-multipart)
  29. - [API](#api)
  30. - [fetch(url[, options])](#fetchurl-options)
  31. - [Options](#options)
  32. - [Class: Request](#class-request)
  33. - [Class: Response](#class-response)
  34. - [Class: Headers](#class-headers)
  35. - [Interface: Body](#interface-body)
  36. - [Class: FetchError](#class-fetcherror)
  37. - [License](#license)
  38. - [Acknowledgement](#acknowledgement)
  39. <!-- /TOC -->
  40. ## Motivation
  41. 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.
  42. See Matt Andrews' [isomorphic-fetch](https://github.com/matthew-andrews/isomorphic-fetch) or Leonardo Quixada's [cross-fetch](https://github.com/lquixada/cross-fetch) for isomorphic usage (exports `node-fetch` for server-side, `whatwg-fetch` for client-side).
  43. ## Features
  44. - Stay consistent with `window.fetch` API.
  45. - Make conscious trade-off when following [WHATWG fetch spec][whatwg-fetch] and [stream spec](https://streams.spec.whatwg.org/) implementation details, document known differences.
  46. - Use native promise, but allow substituting it with [insert your favorite promise library].
  47. - Use native Node streams for body, on both request and response.
  48. - Decode content encoding (gzip/deflate) properly, and convert string output (such as `res.text()` and `res.json()`) to UTF-8 automatically.
  49. - Useful extensions such as timeout, redirect limit, response size limit, [explicit errors](ERROR-HANDLING.md) for troubleshooting.
  50. ## Difference from client-side fetch
  51. - See [Known Differences](LIMITS.md) for details.
  52. - If you happen to use a missing feature that `window.fetch` offers, feel free to open an issue.
  53. - Pull requests are welcomed too!
  54. ## Installation
  55. Current stable release (`2.x`)
  56. ```sh
  57. $ npm install node-fetch --save
  58. ```
  59. ## Loading and configuring the module
  60. We suggest you load the module via `require`, pending the stabalizing of es modules in node:
  61. ```js
  62. const fetch = require('node-fetch');
  63. ```
  64. If you are using a Promise library other than native, set it through fetch.Promise:
  65. ```js
  66. const Bluebird = require('bluebird');
  67. fetch.Promise = Bluebird;
  68. ```
  69. ## Common Usage
  70. NOTE: The documentation below is up-to-date with `2.x` releases, [see `1.x` readme](https://github.com/bitinn/node-fetch/blob/1.x/README.md), [changelog](https://github.com/bitinn/node-fetch/blob/1.x/CHANGELOG.md) and [2.x upgrade guide](UPGRADE-GUIDE.md) for the differences.
  71. #### Plain text or HTML
  72. ```js
  73. fetch('https://github.com/')
  74. .then(res => res.text())
  75. .then(body => console.log(body));
  76. ```
  77. #### JSON
  78. ```js
  79. fetch('https://api.github.com/users/github')
  80. .then(res => res.json())
  81. .then(json => console.log(json));
  82. ```
  83. #### Simple Post
  84. ```js
  85. fetch('https://httpbin.org/post', { method: 'POST', body: 'a=1' })
  86. .then(res => res.json()) // expecting a json response
  87. .then(json => console.log(json));
  88. ```
  89. #### Post with JSON
  90. ```js
  91. const body = { a: 1 };
  92. fetch('https://httpbin.org/post', {
  93. method: 'post',
  94. body: JSON.stringify(body),
  95. headers: { 'Content-Type': 'application/json' },
  96. })
  97. .then(res => res.json())
  98. .then(json => console.log(json));
  99. ```
  100. #### Post with form parameters
  101. `URLSearchParams` is available in Node.js as of v7.5.0. See [official documentation](https://nodejs.org/api/url.html#url_class_urlsearchparams) for more usage methods.
  102. NOTE: The `Content-Type` header is only set automatically to `x-www-form-urlencoded` when an instance of `URLSearchParams` is given as such:
  103. ```js
  104. const { URLSearchParams } = require('url');
  105. const params = new URLSearchParams();
  106. params.append('a', 1);
  107. fetch('https://httpbin.org/post', { method: 'POST', body: params })
  108. .then(res => res.json())
  109. .then(json => console.log(json));
  110. ```
  111. #### Handling exceptions
  112. NOTE: 3xx-5xx responses are *NOT* exceptions, and should be handled in `then()`, see the next section.
  113. Adding a catch to the fetch promise chain will catch *all* exceptions, such as errors originating from node core libraries, like network errors, and operational errors which are instances of FetchError. See the [error handling document](ERROR-HANDLING.md) for more details.
  114. ```js
  115. fetch('https://domain.invalid/')
  116. .catch(err => console.error(err));
  117. ```
  118. #### Handling client and server errors
  119. It is common to create a helper function to check that the response contains no client (4xx) or server (5xx) error responses:
  120. ```js
  121. function checkStatus(res) {
  122. if (res.ok) { // res.status >= 200 && res.status < 300
  123. return res;
  124. } else {
  125. throw MyCustomError(res.statusText);
  126. }
  127. }
  128. fetch('https://httpbin.org/status/400')
  129. .then(checkStatus)
  130. .then(res => console.log('will not get here...'))
  131. ```
  132. ## Advanced Usage
  133. #### Streams
  134. The "Node.js way" is to use streams when possible:
  135. ```js
  136. fetch('https://assets-cdn.github.com/images/modules/logos_page/Octocat.png')
  137. .then(res => {
  138. const dest = fs.createWriteStream('./octocat.png');
  139. res.body.pipe(dest);
  140. });
  141. ```
  142. #### Buffer
  143. If you prefer to cache binary data in full, use buffer(). (NOTE: buffer() is a `node-fetch` only API)
  144. ```js
  145. const fileType = require('file-type');
  146. fetch('https://assets-cdn.github.com/images/modules/logos_page/Octocat.png')
  147. .then(res => res.buffer())
  148. .then(buffer => fileType(buffer))
  149. .then(type => { /* ... */ });
  150. ```
  151. #### Accessing Headers and other Meta data
  152. ```js
  153. fetch('https://github.com/')
  154. .then(res => {
  155. console.log(res.ok);
  156. console.log(res.status);
  157. console.log(res.statusText);
  158. console.log(res.headers.raw());
  159. console.log(res.headers.get('content-type'));
  160. });
  161. ```
  162. #### Post data using a file stream
  163. ```js
  164. const { createReadStream } = require('fs');
  165. const stream = createReadStream('input.txt');
  166. fetch('https://httpbin.org/post', { method: 'POST', body: stream })
  167. .then(res => res.json())
  168. .then(json => console.log(json));
  169. ```
  170. #### Post with form-data (detect multipart)
  171. ```js
  172. const FormData = require('form-data');
  173. const form = new FormData();
  174. form.append('a', 1);
  175. fetch('https://httpbin.org/post', { method: 'POST', body: form })
  176. .then(res => res.json())
  177. .then(json => console.log(json));
  178. // OR, using custom headers
  179. // NOTE: getHeaders() is non-standard API
  180. const form = new FormData();
  181. form.append('a', 1);
  182. const options = {
  183. method: 'POST',
  184. body: form,
  185. headers: form.getHeaders()
  186. }
  187. fetch('https://httpbin.org/post', options)
  188. .then(res => res.json())
  189. .then(json => console.log(json));
  190. ```
  191. See [test cases](https://github.com/bitinn/node-fetch/blob/master/test/test.js) for more examples.
  192. ## API
  193. ### fetch(url[, options])
  194. - `url` A string representing the URL for fetching
  195. - `options` [Options](#fetch-options) for the HTTP(S) request
  196. - Returns: <code>Promise&lt;[Response](#class-response)&gt;</code>
  197. Perform an HTTP(S) fetch.
  198. `url` should be an absolute url, such as `https://example.com/`. A path-relative URL (`/file/under/root`) or protocol-relative URL (`//can-be-http-or-https.com/`) will result in a rejected promise.
  199. <a id="fetch-options"></a>
  200. ### Options
  201. The default values are shown after each option key.
  202. ```js
  203. {
  204. // These properties are part of the Fetch Standard
  205. method: 'GET',
  206. headers: {}, // request headers. format is the identical to that accepted by the Headers constructor (see below)
  207. body: null, // request body. can be null, a string, a Buffer, a Blob, or a Node.js Readable stream
  208. redirect: 'follow', // set to `manual` to extract redirect headers, `error` to reject redirect
  209. // The following properties are node-fetch extensions
  210. follow: 20, // maximum redirect count. 0 to not follow redirect
  211. timeout: 0, // req/res timeout in ms, it resets on redirect. 0 to disable (OS limit applies)
  212. compress: true, // support gzip/deflate content encoding. false to disable
  213. size: 0, // maximum response body size in bytes. 0 to disable
  214. agent: null // http(s).Agent instance, allows custom proxy, certificate, dns lookup etc.
  215. }
  216. ```
  217. ##### Default Headers
  218. If no values are set, the following request headers will be sent automatically:
  219. Header | Value
  220. ------------------- | --------------------------------------------------------
  221. `Accept-Encoding` | `gzip,deflate` _(when `options.compress === true`)_
  222. `Accept` | `*/*`
  223. `Connection` | `close` _(when no `options.agent` is present)_
  224. `Content-Length` | _(automatically calculated, if possible)_
  225. `Transfer-Encoding` | `chunked` _(when `req.body` is a stream)_
  226. `User-Agent` | `node-fetch/1.0 (+https://github.com/bitinn/node-fetch)`
  227. <a id="class-request"></a>
  228. ### Class: Request
  229. An HTTP(S) request containing information about URL, method, headers, and the body. This class implements the [Body](#iface-body) interface.
  230. Due to the nature of Node.js, the following properties are not implemented at this moment:
  231. - `type`
  232. - `destination`
  233. - `referrer`
  234. - `referrerPolicy`
  235. - `mode`
  236. - `credentials`
  237. - `cache`
  238. - `integrity`
  239. - `keepalive`
  240. The following node-fetch extension properties are provided:
  241. - `follow`
  242. - `compress`
  243. - `counter`
  244. - `agent`
  245. See [options](#fetch-options) for exact meaning of these extensions.
  246. #### new Request(input[, options])
  247. <small>*(spec-compliant)*</small>
  248. - `input` A string representing a URL, or another `Request` (which will be cloned)
  249. - `options` [Options][#fetch-options] for the HTTP(S) request
  250. Constructs a new `Request` object. The constructor is identical to that in the [browser](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request).
  251. In most cases, directly `fetch(url, options)` is simpler than creating a `Request` object.
  252. <a id="class-response"></a>
  253. ### Class: Response
  254. An HTTP(S) response. This class implements the [Body](#iface-body) interface.
  255. The following properties are not implemented in node-fetch at this moment:
  256. - `Response.error()`
  257. - `Response.redirect()`
  258. - `type`
  259. - `redirected`
  260. - `trailer`
  261. #### new Response([body[, options]])
  262. <small>*(spec-compliant)*</small>
  263. - `body` A string or [Readable stream][node-readable]
  264. - `options` A [`ResponseInit`][response-init] options dictionary
  265. Constructs a new `Response` object. The constructor is identical to that in the [browser](https://developer.mozilla.org/en-US/docs/Web/API/Response/Response).
  266. Because Node.js does not implement service workers (for which this class was designed), one rarely has to construct a `Response` directly.
  267. #### response.ok
  268. <small>*(spec-compliant)*</small>
  269. Convenience property representing if the request ended normally. Will evaluate to true if the response status was greater than or equal to 200 but smaller than 300.
  270. <a id="class-headers"></a>
  271. ### Class: Headers
  272. This class allows manipulating and iterating over a set of HTTP headers. All methods specified in the [Fetch Standard][whatwg-fetch] are implemented.
  273. #### new Headers([init])
  274. <small>*(spec-compliant)*</small>
  275. - `init` Optional argument to pre-fill the `Headers` object
  276. Construct a new `Headers` object. `init` can be either `null`, a `Headers` object, an key-value map object, or any iterable object.
  277. ```js
  278. // Example adapted from https://fetch.spec.whatwg.org/#example-headers-class
  279. const meta = {
  280. 'Content-Type': 'text/xml',
  281. 'Breaking-Bad': '<3'
  282. };
  283. const headers = new Headers(meta);
  284. // The above is equivalent to
  285. const meta = [
  286. [ 'Content-Type', 'text/xml' ],
  287. [ 'Breaking-Bad', '<3' ]
  288. ];
  289. const headers = new Headers(meta);
  290. // You can in fact use any iterable objects, like a Map or even another Headers
  291. const meta = new Map();
  292. meta.set('Content-Type', 'text/xml');
  293. meta.set('Breaking-Bad', '<3');
  294. const headers = new Headers(meta);
  295. const copyOfHeaders = new Headers(headers);
  296. ```
  297. <a id="iface-body"></a>
  298. ### Interface: Body
  299. `Body` is an abstract interface with methods that are applicable to both `Request` and `Response` classes.
  300. The following methods are not yet implemented in node-fetch at this moment:
  301. - `formData()`
  302. #### body.body
  303. <small>*(deviation from spec)*</small>
  304. * Node.js [`Readable` stream][node-readable]
  305. The data encapsulated in the `Body` object. Note that while the [Fetch Standard][whatwg-fetch] requires the property to always be a WHATWG `ReadableStream`, in node-fetch it is a Node.js [`Readable` stream][node-readable].
  306. #### body.bodyUsed
  307. <small>*(spec-compliant)*</small>
  308. * `Boolean`
  309. A boolean property for if this body has been consumed. Per spec, a consumed body cannot be used again.
  310. #### body.arrayBuffer()
  311. #### body.blob()
  312. #### body.json()
  313. #### body.text()
  314. <small>*(spec-compliant)*</small>
  315. * Returns: <code>Promise</code>
  316. Consume the body and return a promise that will resolve to one of these formats.
  317. #### body.buffer()
  318. <small>*(node-fetch extension)*</small>
  319. * Returns: <code>Promise&lt;Buffer&gt;</code>
  320. Consume the body and return a promise that will resolve to a Buffer.
  321. #### body.textConverted()
  322. <small>*(node-fetch extension)*</small>
  323. * Returns: <code>Promise&lt;String&gt;</code>
  324. Identical to `body.text()`, except instead of always converting to UTF-8, encoding sniffing will be performed and text converted to UTF-8, if possible.
  325. (This API requires an optional dependency on npm package [encoding](https://www.npmjs.com/package/encoding), which you need to install manually. `webpack` users may see [a warning message](https://github.com/bitinn/node-fetch/issues/412#issuecomment-379007792) due to this optional dependency.)
  326. <a id="class-fetcherror"></a>
  327. ### Class: FetchError
  328. <small>*(node-fetch extension)*</small>
  329. An operational error in the fetching process. See [ERROR-HANDLING.md][] for more info.
  330. ## Acknowledgement
  331. Thanks to [github/fetch](https://github.com/github/fetch) for providing a solid implementation reference.
  332. `node-fetch` v1 was maintained by [@bitinn](https://github.com/bitinn), v2 is currently maintained by [@TimothyGu](https://github.com/timothygu), v2 readme is written by [@jkantr](https://github.com/jkantr).
  333. ## License
  334. MIT
  335. [npm-image]: https://img.shields.io/npm/v/node-fetch.svg?style=flat-square
  336. [npm-url]: https://www.npmjs.com/package/node-fetch
  337. [travis-image]: https://img.shields.io/travis/bitinn/node-fetch.svg?style=flat-square
  338. [travis-url]: https://travis-ci.org/bitinn/node-fetch
  339. [codecov-image]: https://img.shields.io/codecov/c/github/bitinn/node-fetch.svg?style=flat-square
  340. [codecov-url]: https://codecov.io/gh/bitinn/node-fetch
  341. [install-size-image]: https://packagephobia.now.sh/badge?p=node-fetch
  342. [install-size-url]: https://packagephobia.now.sh/result?p=node-fetch
  343. [whatwg-fetch]: https://fetch.spec.whatwg.org/
  344. [response-init]: https://fetch.spec.whatwg.org/#responseinit
  345. [node-readable]: https://nodejs.org/api/stream.html#stream_readable_streams
  346. [mdn-headers]: https://developer.mozilla.org/en-US/docs/Web/API/Headers
  347. [LIMITS.md]: https://github.com/bitinn/node-fetch/blob/master/LIMITS.md
  348. [ERROR-HANDLING.md]: https://github.com/bitinn/node-fetch/blob/master/ERROR-HANDLING.md
  349. [UPGRADE-GUIDE.md]: https://github.com/bitinn/node-fetch/blob/master/UPGRADE-GUIDE.md