Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

node-fetch2

cityofsurrey951MIT1.6.3

A light-weight module that brings window.fetch to node.js and io.js

fetch, http, promise

readme

node-fetch

npm version build status coverage status

A light-weight module that brings window.fetch to Node.js

Motivation

Instead of implementing XMLHttpRequest in Node.js to run browser-specific Fetch polyfill, 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.

See Matt Andrews' isomorphic-fetch for isomorphic usage (exports node-fetch for server-side, whatwg-fetch for client-side).

Features

  • Stay consistent with window.fetch API.
  • Make conscious trade-off when following whatwg fetch spec and stream spec implementation details, document known difference.
  • Use native promise, but allow substituting it with [insert your favorite promise library].
  • Use native stream for body, on both request and response.
  • Decode content encoding (gzip/deflate) properly, and convert string output (such as res.text() and res.json()) to UTF-8 automatically.
  • Useful extensions such as timeout, redirect limit, response size limit, explicit errors for troubleshooting.

Difference from client-side fetch

  • See Known Differences for details.
  • If you happen to use a missing feature that window.fetch offers, feel free to open an issue.
  • Pull requests are welcomed too!

Install

npm install node-fetch --save

Usage

import fetch from 'node-fetch';
// or
// const fetch = require('node-fetch');

// if you are using your own Promise library, set it through fetch.Promise. Eg.

// import Bluebird from 'bluebird';
// fetch.Promise = Bluebird;

// plain text or html

fetch('https://github.com/')
    .then(res => res.text())
    .then(body => console.log(body));

// json

fetch('https://api.github.com/users/github')
    .then(res => res.json())
    .then(json => console.log(json));

// 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/')
    .catch(err => console.error(err));

// stream
// the node.js way is to use stream when possible

fetch('https://assets-cdn.github.com/images/modules/logos_page/Octocat.png')
    .then(res => {
        const dest = fs.createWriteStream('./octocat.png');
        res.body.pipe(dest);
    });

// buffer
// if you prefer to cache binary data in full, use buffer()
// note that buffer() is a node-fetch only API

import fileType from 'file-type';

fetch('https://assets-cdn.github.com/images/modules/logos_page/Octocat.png')
    .then(res => res.buffer())
    .then(buffer => fileType(buffer))
    .then(type => { /* ... */ });

// meta

fetch('https://github.com/')
    .then(res => {
        console.log(res.ok);
        console.log(res.status);
        console.log(res.statusText);
        console.log(res.headers.raw());
        console.log(res.headers.get('content-type'));
    });

// post

fetch('http://httpbin.org/post', { method: 'POST', body: 'a=1' })
    .then(res => res.json())
    .then(json => console.log(json));

// post with stream from file

import { createReadStream } from 'fs';

const stream = createReadStream('input.txt');
fetch('http://httpbin.org/post', { method: 'POST', body: stream })
    .then(res => res.json())
    .then(json => console.log(json));

// post with JSON

var body = { a: 1 };
fetch('http://httpbin.org/post', { 
    method: 'POST',
    body:    JSON.stringify(body),
    headers: { 'Content-Type': 'application/json' },
})
    .then(res => res.json())
    .then(json => console.log(json));

// post with form-data (detect multipart)

import FormData from 'form-data';

const form = new FormData();
form.append('a', 1);
fetch('http://httpbin.org/post', { method: 'POST', body: form })
    .then(res => res.json())
    .then(json => console.log(json));

// post with form-data (custom headers)
// note that getHeaders() is non-standard API

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() })
    .then(res => res.json())
    .then(json => console.log(json));

// node 7+ with async function

(async function () {
    const res = await fetch('https://api.github.com/users/github');
    const json = await res.json();
    console.log(json);
})();

See test cases for more examples.

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.

{
    method: 'GET'
    , headers: {}        // request header. format {a:'1'} or {b:['1','2','3']}
    , redirect: 'follow' // set to `manual` to extract redirect headers, `error` to reject redirect
    , follow: 20         // maximum redirect count. 0 to not follow redirect
    , timeout: 0         // req/res timeout in ms, it resets on redirect. 0 to disable (OS limit applies)
    , 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.
}

License

MIT

Acknowledgement

Thanks to github/fetch for providing a solid implementation reference.

changelog

Changelog

2.x release

v2.0.0-alpha.1 (UNRELEASED)

  • Major: Node.js 0.10.x support is dropped
  • Major: rewrite in transpiled ES2015
  • Major: internal methods are no longer exposed
  • Major: throw error when a GET/HEAD Request is constructed with a non-null body (per spec)
  • Major: response.text() no longer attempts to detect encoding, instead always opting for UTF-8 (per spec); use response.textConverted() for the old behavior
  • Major: make response.json() throw error instead of returning an empty object on 204 no-content respose (per spec; reverts behavior set in v1.6.2)
  • Major: arrays as parameters to headers.append and headers.set are joined as a string (per spec)
  • Enhance: start testing on Node.js 4, 6, 7
  • Enhance: use Rollup to produce a distributed bundle (less memory overhead and faster startup)
  • Enhance: make toString() on Headers, Requests, and Responses return correct IDL class strings
  • Enhance: add an option to conform to latest spec at the expense of reduced compatibility
  • Enhance: set Content-Length header for Buffers as well
  • Enhance: add response.arrayBuffer() (also applies to Requests)
  • Enhance: add experimental response.blob() (also applies to Requests)
  • Enhance: make Headers iterable
  • Enhance: make Headers constructor accept an array of tuples
  • Enhance: make sure header names and values are valid in HTTP
  • Fix: coerce Headers prototype function parameters to strings, where applicable
  • Fix: fix Request and Response with null body
  • Fix: support WHATWG URL objects, created by whatwg-url package or require('url').URL in Node.js 7+
  • Other: use Codecov for code coverage tracking

1.x release

v1.6.3

  • Enhance: error handling document to explain FetchError design
  • Fix: support form-data 2.x releases (requires form-data >= 2.1.0)

v1.6.2

  • Enhance: minor document update
  • Fix: response.json() returns empty object on 204 no-content response instead of throwing a syntax error

v1.6.1

  • Fix: if res.body is a non-stream non-formdata object, we will call body.toString and send it as a string
  • Fix: counter value is incorrectly set to follow value when wrapping Request instance
  • Fix: documentation update

v1.6.0

  • Enhance: added res.buffer() api for convenience, it returns body as a Node.js buffer
  • Enhance: better old server support by handling raw deflate response
  • Enhance: skip encoding detection for non-HTML/XML response
  • Enhance: minor document update
  • Fix: HEAD request doesn't need decompression, as body is empty
  • Fix: req.body now accepts a Node.js buffer

v1.5.3

  • Fix: handle 204 and 304 responses when body is empty but content-encoding is gzip/deflate
  • Fix: allow resolving response and cloned response in any order
  • Fix: avoid setting content-length when form-data body use streams
  • Fix: send DELETE request with content-length when body is present
  • Fix: allow any url when calling new Request, but still reject non-http(s) url in fetch

v1.5.2

  • Fix: allow node.js core to handle keep-alive connection pool when passing a custom agent

v1.5.1

  • Fix: redirect mode manual should work even when there is no redirection or broken redirection

v1.5.0

  • Enhance: rejected promise now use custom Error (thx to @pekeler)
  • Enhance: FetchError contains err.type and err.code, allows for better error handling (thx to @pekeler)
  • Enhance: basic support for redirect mode manual and error, allows for location header extraction (thx to @jimmywarting for the initial PR)

v1.4.1

  • Fix: wrapping Request instance with FormData body again should preserve the body as-is

v1.4.0

  • Enhance: Request and Response now have clone method (thx to @kirill-konshin for the initial PR)
  • Enhance: Request and Response now have proper string and buffer body support (thx to @kirill-konshin)
  • Enhance: Body constructor has been refactored out (thx to @kirill-konshin)
  • Enhance: Headers now has forEach method (thx to @tricoder42)
  • Enhance: back to 100% code coverage
  • Fix: better form-data support (thx to @item4)
  • Fix: better character encoding detection under chunked encoding (thx to @dsuket for the initial PR)

v1.3.3

  • Fix: make sure Content-Length header is set when body is string for POST/PUT/PATCH requests
  • Fix: handle body stream error, for cases such as incorrect Content-Encoding header
  • Fix: when following certain redirects, use GET on subsequent request per Fetch Spec
  • Fix: Request and Response constructors now parse headers input using Headers

v1.3.2

  • Enhance: allow auto detect of form-data input (no FormData spec on node.js, this is form-data specific feature)

v1.3.1

  • Enhance: allow custom host header to be set (server-side only feature, as it's a forbidden header on client-side)

v1.3.0

  • Enhance: now fetch.Request is exposed as well

v1.2.1

  • Enhance: Headers now normalized Number value to String, prevent common mistakes

v1.2.0

  • Enhance: now fetch.Headers and fetch.Response are exposed, making testing easier

v1.1.2

  • Fix: Headers should only support String and Array properties, and ignore others

v1.1.1

  • Enhance: now req.headers accept both plain object and Headers instance

v1.1.0

  • Enhance: timeout now also applies to response body (in case of slow response)
  • Fix: timeout is now cleared properly when fetch is done/has failed

v1.0.6

  • Fix: less greedy content-type charset matching

v1.0.5

  • Fix: when follow = 0, fetch should not follow redirect
  • Enhance: update tests for better coverage
  • Enhance: code formatting
  • Enhance: clean up doc

v1.0.4

  • Enhance: test iojs support
  • Enhance: timeout attached to socket event only fire once per redirect

v1.0.3

  • Fix: response size limit should reject large chunk
  • Enhance: added character encoding detection for xml, such as rss/atom feed (encoding in DTD)

v1.0.2

  • Fix: added res.ok per spec change

v1.0.0

  • Enhance: better test coverage and doc

0.x release

v0.1

  • Major: initial public release