【问题标题】:How can I download and save a file using the Fetch API? (Node.js)如何使用 Fetch API 下载和保存文件? (Node.js)
【发布时间】:2016-10-03 12:51:58
【问题描述】:

我有一个可能很大 (100+ Mb) 文件的 url,如何使用 fetch 将其保存在本地目录中?

我环顾四周,但似乎没有很多关于如何做到这一点的资源/教程。

谢谢!

【问题讨论】:

  • Node.js 没有集成 Fetch。
  • 为什么要抓取? Node 支持 http 吗?
  • 我正在创建一个 Electron 应用,支持 fetch。为什么要 fetch 而不是纯 http,因为它更容易使用(或者到目前为止看起来如此)。
  • 如果有人在浏览器中寻找使用 fetch api 保存文件的方法(并遇到了这个答案),那么请看这里:stackoverflow.com/a/42274086/350384

标签: javascript node.js xmlhttprequest fetch fetch-api


【解决方案1】:

使用 Fetch API,您可以编写一个可以从如下 URL 下载的函数:

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);
    });
});

【讨论】:

  • 您甚至可以通过编写 res.body.on('error', reject);fileStream.on('finish', resolve); 来缩短它。
【解决方案2】:

如果您想避免像其他非常好的答案那样明确地做出承诺,并且可以构建整个 100+ MB 文件的缓冲区,那么您可以做一些更简单的事情:

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)));
}

但另一个答案会更节省内存,因为它将接收到的数据流直接传输到文件中,而不会将所有数据流累积到缓冲区中。

【讨论】:

    【解决方案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)
    );
    

    【讨论】:

    • 我收到错误TypeError: Cannot read property 'on' of undefined at destroyer (internal/streams/pipeline.js:23:10)
    猜你喜欢
    • 1970-01-01
    • 2022-12-18
    • 2021-08-08
    • 1970-01-01
    • 2017-10-25
    • 2016-10-03
    • 2010-10-29
    • 1970-01-01
    相关资源
    最近更新 更多