Node.js和请求"/>
Node.js和请求
我想使用请求库下载文件。这很简单:
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));
问题是-这有多可靠?我猜这个回调将被称为after文件已下载,对吗?但是,如果有人提供文件的URL为1 GB,为时已晚。我的应用程序将首先下载这1 GB的文件,只是为了检查(在回调中)该文件太大。
我也在考虑好的旧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
标头,并观察数据流以确保它不超出您的限制。
为此,我首先向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
模块那样)。如果数据大小超出最大文件大小,请调用响应的abort()
方法。
更多推荐
Node.js和请求
发布评论