├── .editorconfig ├── .gitignore ├── .jshintrc ├── .travis.yml ├── LICENSE ├── README.md ├── bower.json ├── fetch-bower.js ├── fetch-npm-browserify.js ├── fetch-npm-node.js ├── package.json └── test └── api.test.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root=true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | 7 | [*.js] 8 | indent_style = tab 9 | 10 | [*.json] 11 | indent_style = space 12 | indent_size = 2 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | /bower_components/ 3 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "browser": true, 4 | "predef": ["describe", "it", "before"] 5 | } 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - 14 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Matt Andrews 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | isomorphic-fetch [![Build Status](https://travis-ci.org/matthew-andrews/isomorphic-fetch.svg?branch=master)](https://travis-ci.org/matthew-andrews/isomorphic-fetch) 2 | ================ 3 | 4 | Fetch for node and Browserify. Built on top of [GitHub's WHATWG Fetch polyfill](https://github.com/github/fetch). 5 | 6 | ## Warnings 7 | 8 | - This adds `fetch` as a global so that its API is consistent between client and server. 9 | 10 | For [ease-of-maintenance and backward-compatibility reasons][why polyfill], this library will always be a polyfill. As a "safe" alternative, which does not modify the global, consider [fetch-ponyfill][]. 11 | 12 | [why polyfill]: https://github.com/matthew-andrews/isomorphic-fetch/issues/31#issuecomment-149668361 13 | [fetch-ponyfill]: https://github.com/qubyte/fetch-ponyfill 14 | 15 | ## Why Use Isomorphic Fetch 16 | 17 | The Fetch API is currently [not implemented consistently](http://caniuse.com/#search=fetch) across browsers. This module will enable you to use `fetch` in your Node code in a cross-browser compliant fashion. The Fetch API is part of the Web platform API defined by the standards bodies WHATWG and W3C. 18 | 19 | ## Installation 20 | 21 | ### NPM 22 | 23 | ```sh 24 | npm install --save isomorphic-fetch 25 | ``` 26 | 27 | ### Bower 28 | 29 | ```sh 30 | bower install --save isomorphic-fetch 31 | ``` 32 | 33 | ## Usage 34 | 35 | ```js 36 | require('isomorphic-fetch'); 37 | 38 | fetch('//offline-news-api.herokuapp.com/stories') 39 | .then(function(response) { 40 | if (response.status >= 400) { 41 | throw new Error("Bad response from server"); 42 | } 43 | return response.json(); 44 | }) 45 | .then(function(stories) { 46 | console.log(stories); 47 | }); 48 | ``` 49 | 50 | ## License 51 | 52 | All open source code released by FT Labs is licenced under the MIT licence. Based on [the fine work by](https://github.com/github/fetch/pull/31) **[jxck](https://github.com/Jxck)**. 53 | 54 | ## Alternatives 55 | 56 | - [cross-fetch](https://github.com/lquixada/cross-fetch#why-not-isomorphic-fetch) 57 | - Using [node-fetch](https://github.com/node-fetch/node-fetch) and the [Fetch polyfill](https://github.com/github/fetch) directly (or from [polyfill.io](https://polyfill.io), or relying on [the browser's implementation of the Fetch API](https://caniuse.com/fetch)). 58 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "isomorphic-fetch", 3 | "main": ["fetch-bower.js"], 4 | "dependencies": { 5 | "fetch": "github/fetch#^3.4.1" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /fetch-bower.js: -------------------------------------------------------------------------------- 1 | module.exports = require('fetch'); 2 | -------------------------------------------------------------------------------- /fetch-npm-browserify.js: -------------------------------------------------------------------------------- 1 | // the whatwg-fetch polyfill installs the fetch() function 2 | // on the global object (window or self) 3 | // 4 | // Return that as the export for use in Webpack, Browserify etc. 5 | require('whatwg-fetch'); 6 | module.exports = self.fetch.bind(self); 7 | -------------------------------------------------------------------------------- /fetch-npm-node.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var realFetch = require('node-fetch'); 4 | module.exports = function(url, options) { 5 | if (/^\/\//.test(url)) { 6 | url = 'https:' + url; 7 | } 8 | return realFetch.call(this, url, options); 9 | }; 10 | 11 | if (!global.fetch) { 12 | global.fetch = module.exports; 13 | global.Response = realFetch.Response; 14 | global.Headers = realFetch.Headers; 15 | global.Request = realFetch.Request; 16 | } 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "isomorphic-fetch", 3 | "version": "3.0.0", 4 | "description": "Isomorphic WHATWG Fetch API, for Node & Browserify", 5 | "browser": "fetch-npm-browserify.js", 6 | "main": "fetch-npm-node.js", 7 | "scripts": { 8 | "files": "find . -name '*.js' ! -path './node_modules/*' ! -path './bower_components/*'", 9 | "test": "jshint `npm run -s files` && lintspaces -i js-comments -e .editorconfig `npm run -s files` && mocha" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/matthew-andrews/isomorphic-fetch.git" 14 | }, 15 | "author": "Matt Andrews ", 16 | "license": "MIT", 17 | "bugs": { 18 | "url": "https://github.com/matthew-andrews/isomorphic-fetch/issues" 19 | }, 20 | "homepage": "https://github.com/matthew-andrews/isomorphic-fetch/issues", 21 | "dependencies": { 22 | "node-fetch": "^2.6.1", 23 | "whatwg-fetch": "^3.4.1" 24 | }, 25 | "devDependencies": { 26 | "chai": "^4.2.0", 27 | "jshint": "^2.5.11", 28 | "lintspaces-cli": "^0.7.1", 29 | "mocha": "^8.1.3", 30 | "nock": "^13.0.4" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test/api.test.js: -------------------------------------------------------------------------------- 1 | /*global fetch*/ 2 | "use strict"; 3 | 4 | require('../fetch-npm-node'); 5 | var expect = require('chai').expect; 6 | var nock = require('nock'); 7 | var good = 'hello world. 你好世界。'; 8 | var bad = 'good bye cruel world. 再见残酷的世界。'; 9 | 10 | function responseToText(response) { 11 | if (response.status >= 400) throw new Error("Bad server response"); 12 | return response.text(); 13 | } 14 | 15 | describe('fetch', function() { 16 | 17 | before(function() { 18 | nock('https://mattandre.ws') 19 | .get('/succeed.txt') 20 | .reply(200, good); 21 | nock('https://mattandre.ws') 22 | .get('/fail.txt') 23 | .reply(404, bad); 24 | }); 25 | 26 | it('should be defined', function() { 27 | expect(fetch).to.be.a('function'); 28 | }); 29 | 30 | it('should facilitate the making of requests', function(done) { 31 | fetch('//mattandre.ws/succeed.txt') 32 | .then(responseToText) 33 | .then(function(data) { 34 | expect(data).to.equal(good); 35 | done(); 36 | }) 37 | .catch(done); 38 | }); 39 | 40 | it('should do the right thing with bad requests', function(done) { 41 | fetch('//mattandre.ws/fail.txt') 42 | .then(responseToText) 43 | .catch(function(err) { 44 | expect(err.toString()).to.equal("Error: Bad server response"); 45 | done(); 46 | }) 47 | .catch(done); 48 | }); 49 | 50 | }); 51 | --------------------------------------------------------------------------------