How can I download and save a file using the Fetch API? (Node.js)

34,447

Solution 1

Using the Fetch API you could write a function that could download from a URL like this:

const downloadFile = (async (url, path) => {
  const res = await fetch(url);
  const fileStream = fs.createWriteStream(path);
  await new Promise((resolve, reject) => {
      res.body.pipe(fileStream);
      res.body.on("error", reject);
      fileStream.on("finish", resolve);
    });
});

Solution 2

If you want to avoid explicitly making a Promise like in the other very fine answer, and are ok with building a buffer of the entire 100+ MB file, then you could do something simpler:

const fetch = require('node-fetch');
const {writeFile} = require('fs');
const {promisify} = require('util');
const writeFilePromise = promisify(writeFile);

function downloadFile(url, outputPath) {
  return fetch(url)
      .then(x => x.arrayBuffer())
      .then(x => writeFilePromise(outputPath, Buffer.from(x)));
}

But the other answer will be more memory-efficient since it's piping the received data stream directly into a file without accumulating all of it in a Buffer.

Solution 3

const {createWriteStream} = require('fs');
const {pipeline} = require('stream/promises');
const fetch = require('node-fetch');

const downloadFile = async (url, path) => pipeline(
    (await fetch(url)).body,
    createWriteStream(path)
);
Share:
34,447
Gloomy
Author by

Gloomy

Updated on January 05, 2022

Comments

  • Gloomy
    Gloomy over 2 years

    I have the url to a possibly large (100+ Mb) file, how do I save it in a local directory using fetch?

    I looked around but there don't seem to be a lot of resources/tutorials on how to do this.

    Thank you!