Node.js和Request – 限制下载文件的文件大小

我想用请求库下载一个文件。 这很简单:

request({ url: url-to-file }).pipe(fs.createWriteStream(file)); 

由于URL是由用户提供的(在我的情况下),我想限制我的应用程序将下载的最大文件大小 – 比方说10MB。 我可以依靠content-length标题,如下所示:

 request({ url: url-to-file }, function (err, res, body) { var size = parseInt(res.headers['content-length'], 10); if (size > 10485760) { // ooops - file size too large } }).pipe(fs.createWriteStream(file)); 

问题是 – 这有多可靠? 我猜这个callback会在文件被下载调用,对吗? 但是,如果有人提供1 GB的文件的URL,那就太晚了。 我的应用程序将首先下载这个1 GB的文件只是为了检查(在callback),这是太大了。

我也在想好的旧的Node的http.get()方法。 在这种情况下,我会这样做:

 var opts = { host: host, port: port, path: path }; var file = fs.createWriteStream(fileName), fileLength = 0; http.get(opts, function (res) { res.on('data', function (chunk) { fileLength += chunk.length; if (fileLength > 10485760) { // ooops - file size too large file.end(); return res.end(); } file.write(chunk); }).on('end', function () { file.end(); }); }); 

你会推荐什么方法来限制下载最大文件大小,而不是实际下载整个事情,并检查它的大小?

实际上,我将使用您讨论过的两种方法:检查content-legnth标题,并观察数据stream,确保它不超出限制。

要做到这一点,我首先对URL的HEAD请求,看看是否可用的content-length标题。 如果它超过了你的限制,你可以在那里停下来。 如果它不存在或者小于你的限制,请做出实际的GET请求。 由于HEAD请求只会返回头文件而没有实际的内容,这将有助于快速清除有效content-length的大文件。

接下来,制作实际的GET请求并观察传入的数据大小,以确保它不超出限制(这可以通过请求模块完成;参见下文)。 无论HEAD请求是否发现content-length标题,都要作为完整性检查(服务器可能在说明content-length )。

像这样的东西:

 var maxSize = 10485760; request({ url: url, method: "HEAD" }, function(err, headRes) { var size = headRes.headers['content-length']; if (size > maxSize) { console.log('Resource size exceeds limit (' + size + ')'); } else { var file = fs.createWriteStream(filename), size = 0; var res = request({ url: url }); res.on('data', function(data) { size += data.length; if (size > maxSize) { console.log('Resource stream exceeded limit (' + size + ')'); res.abort(); // Abort the response (close and cleanup the stream) fs.unlink(filename); // Delete the file we were downloading the data to } }).pipe(file); } }); 

使用请求模块观察传入数据大小的技巧是在响应中绑定到data事件(如您正在考虑使用http模块),然后再开始将其传输到文件stream。 如果数据大小超过最大文件大小,请调用响应的abort()方法。