For Node with Promise support, a simple Node shim for (part of the) Fetch API requires only a smattering of extra code compared to other answers:
const fs = require(`fs`); const http = require(`http`); const https = require(`https`); module.exports = function fetch(url) { return new Promise((resolve, reject) => { const data = []; const client = url.startsWith("https") ? https : http; client .request(url, (res) => { res.on(`data`, (chunk) => data.push(chunk)); res.on(`end`, () => { const asBytes = Buffer.concat(data); const asString = bytes.toString(`utf8`); resolve({ arrayBuffer: async () => asBytes, json: async () => JSON.parse(asString), text: async () => asString, }); }); res.on(`error`, (e) => reject(e)); }) .end(); }); }; Which you can then use to whatever you need using normal fetch syntax:
const fetch = require(`./tiny-fetch.js`); fetch(`https://placekitten.com/200/300`) .then(res => res.arrayBuffer()) .then(bytes => fs.writeFileSync(`kitten.jpg`, bytes)) .catch(e => console.error(e)); fetch(`https://jsonplaceholder.typicode.com/todos/1`) .then(res => res.json()) .then(obj => console.log(obj)) .catch(e => console.error(e)); // etc.