如何使用Node.js下载文件(不使用第三方库)?

本文介绍如何使用Node.js在不依赖第三方库的情况下从给定URL下载文件,并将其保存到指定目录。通过创建HTTP GET请求并将响应流式传输到文件,文章提供了实现这一功能的详细代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文翻译自:How to download a file with Node.js (without using third-party libraries)?

How do I download a file with Node.js without using third-party libraries ? 如何在不使用第三方库的情况下使用 Node.js下载文件?

I don't need anything special. 我不需要什么特别的东西。 I only want to download a file from a given URL, and then save it to a given directory. 我只想从给定的URL下载文件,然后将其保存到给定的目录。


#1楼

参考:https://stackoom.com/question/o7QC/如何使用Node-js下载文件-不使用第三方库


#2楼

You can create an HTTP GET request and pipe its response into a writable file stream: 您可以创建HTTP GET请求并将其response通过管道response到可写文件流中:

const http = require('http');
const fs = require('fs');

const file = fs.createWriteStream("file.jpg");
const request = http.get("http://i3.ytimg.com/vi/J---aiyznGQ/mqdefault.jpg", function(response) {
  response.pipe(file);
});

If you want to support gathering information on the command line--like specifying a target file or directory, or URL--check out something like Commander . 如果要支持在命令行上收集信息(例如指定目标文件或目录或URL),请查看Commander之类的内容


#3楼

As Michelle Tilley said, but with the appropriate control flow: 正如Michelle Tilley所说,但具有适当的控制流程:

var http = require('http');
var fs = require('fs');

var download = function(url, dest, cb) {
  var file = fs.createWriteStream(dest);
  var request = http.get(url, function(response) {
    response.pipe(file);
    file.on('finish', function() {
      file.close(cb);
    });
  });
}

Without waiting for the finish event, naive scripts may end up with an incomplete file. 不等待finish事件,天真的脚本可能会以不完整的文件结尾。

Edit: Thanks to @Augusto Roman for pointing out that cb should be passed to file.close , not called explicitly. 编辑:感谢@Augusto Roman指出cb应该传递给file.close ,而不是显式调用。


#4楼

gfxmonk's answer has a very tight data race between the callback and the file.close() completing. gfxmonk的答案在回调和file.close()完成之间有非常紧密的数据竞争。 file.close() actually takes a callback that is called when the close has completed. file.close()实际上接受关闭完成时调用的回调。 Otherwise, immediate uses of the file may fail (very rarely!). 否则,该文件的立即使用可能会失败(非常罕见!)。

A complete solution is: 完整的解决方案是:

var http = require('http');
var fs = require('fs');

var download = function(url, dest, cb) {
  var file = fs.createWriteStream(dest);
  var request = http.get(url, function(response) {
    response.pipe(file);
    file.on('finish', function() {
      file.close(cb);  // close() is async, call cb after close completes.
    });
  });
}

Without waiting for the finish event, naive scripts may end up with an incomplete file. 不等待完成事件,天真的脚本可能会以不完整的文件结尾。 Without scheduling the cb callback via close, you may get a race between accessing the file and the file actually being ready. 如果不通过close安排cb回调,则可能会在访问文件和实际准备好文件之间产生竞争。


#5楼

Don't forget to handle errors! 不要忘记处理错误! The following code is based on Augusto Roman's answer. 以下代码基于Augusto Roman的答案。

var http = require('http');
var fs = require('fs');

var download = function(url, dest, cb) {
  var file = fs.createWriteStream(dest);
  var request = http.get(url, function(response) {
    response.pipe(file);
    file.on('finish', function() {
      file.close(cb);  // close() is async, call cb after close completes.
    });
  }).on('error', function(err) { // Handle errors
    fs.unlink(dest); // Delete the file async. (But we don't check the result)
    if (cb) cb(err.message);
  });
};

#6楼

Solution with timeout, prevent memory leak : 解决超时问题,防止内存泄漏:

The following code is based on Brandon Tilley's answer : 以下代码基于Brandon Tilley的答案:

var http = require('http'),
    fs = require('fs');

var request = http.get("http://example12345.com/yourfile.html", function(response) {
    if (response.statusCode === 200) {
        var file = fs.createWriteStream("copy.html");
        response.pipe(file);
    }
    // Add timeout.
    request.setTimeout(12000, function () {
        request.abort();
    });
});

Don't make file when you get an error, and prefere to use timeout to close your request after X secondes. 出现错误时不要制作文件,而是希望在X秒后使用超时来关闭请求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值