我正在尝试从网址列表中下载一些文件,但我不想下载超过一定大小的任何内容(比方说1mb)。这些文件可能是千兆字节,因此我需要一种方法在响应流大于1mb时立即取消下载。
let request = require("request");
function getFile(url, callback) {
request.get(url)
.on('response', function(response) {
let output = "";
response.on('data', function(chunk) {
if(output.length > 1000000) {
// ??? ABORT STREAM HERE ???
console.log(`${url} is too big`);
callback(true);
} else {
output += chunk.toString("utf8");
}
});
response.on('end', function() {
console.log(`${url} download complete`);
callback(null, output);
});
});
}
我不知道如何实现这一目标。 This github issue for the request library谈到中止请求,但我认为我想中止实际的 http响应流而不是请求。有一个类似的问题被问到here,但回答者似乎暗示这是不可能的。我确定这不是真的(或者我误解了他们的答案)因为否则我将被迫下载我遇到的每个10gig文件。
是否像删除data
和end
事件侦听器一样简单?直觉上我猜测下载会继续是否附加事件,但我真的不知道它是如何在幕后工作的。感谢您提供的任何帮助!
答案 0 :(得分:1)
我用这个玩了一下,结果发现request
包的.abort()
方法 取消了http响应流。
我希望有一种更通用的方法来取消不依赖于请求包的http响应流,但这样做符合我的目的,因为我目前正在使用请求库。
let request = require("request");
function getFile(url, callback) {
let tooBig = false;
let r = request.get(url)
.on('error', callback)
.on('response', function(response) {
let output = "";
response.on('error', function(error) {
callback(error, null);
});
response.on('data', function(chunk) {
if(output.length > 1000000) {
tooBig = true;
r.abort();
} else {
output += chunk.toString("utf8");
}
});
response.on('end', function() {
if(tooBig) {
console.log(`${url} was too big`);
callback("too big", null);
} else {
console.log(`${url} download complete`);
callback(null, output);
}
});
});
}
此外,如果您正在使用请求库,那么事情可以简化一些:
function getFileSimplified(url, callback) {
let output = "";
let tooBig = false;
let r = request.get(url)
.on('error', callback)
.on('data', function(chunk) {
if(output.length > 1000000) {
tooBig = true;
r.abort();
} else {
output += chunk.toString("utf8");
}
})
.on('end', function() {
if(tooBig) {
console.log(`${url} was too big`);
callback("too big", null);
} else {
console.log(`${url} download complete`);
callback(null, output);
}
})
}
希望能帮助遇到类似问题的人。我不会接受这个答案,因为问题的正确答案不应该取决于npm请求包。如果有人知道该怎么做,请发一个答案,我会接受。