[英]Node.js and Request - limiting the file size of downloaded file
我想下載一個帶有請求庫的文件。 這很簡單:
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));
問題是 - 這有多可靠? 我想這個回調會在文件下載后調用,對嗎? 但是,如果有人提供 1 GB 的文件 URL,那就太晚了。 我的應用程序將首先下載這 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);
}
});
使用 request 模塊觀察傳入數據大小的技巧是在開始將data
到文件流之前綁定到響應上的data
事件(就像您正在考慮使用http
模塊一樣)。 如果數據大小超過您的最大文件大小,請調用響應的abort()
方法。
我有一個類似的問題。 我現在使用fetch來限制下載大小。
const response = await fetch(url, {
method: 'GET',t
size: 5000000, // maximum response body size in bytes, 5000000 = 5MB
}).catch(e => { throw e })
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.