我想设置简化的HTTP请求()客户端包,以中止下载过大的HTTP资源。假设已经设置了request()来下载一个URL,而资源大小为5GB。我希望request()在下载10MB后停止下载。通常,当request()得到一个答案时,它会得到所有的HTTP头和所有内容。一旦您处理数据,您已经拥有了所有已下载的数据。在axios中,有一个名为maxContentLength的参数,但我找不到类似于request()的任何内容。我还必须提到,我不希望它捕获错误,而只是下载至少标题和资源的开头。
const request = require('request');
const URL = 'http://de.releases.ubuntu.com/xenial/ubuntu-16.04.3-desktop-amd64.iso';
const MAX_SIZE = 10 * 1024 * 1024 // 10MB , maximum size to download
let total_bytes_read = 0;
1 - 如果服务器响应是gzip压缩的,您应该启用gzip选项。 https://github.com/request/request#examples为了向后兼容,默认情况下不支持响应压缩。 要接受gzip压缩的响应,请将gzip选项设置为true。
request
.get({
uri: URL,
gzip: true
})
.on('error', function (error) {
//TODO: error handling
console.error('ERROR::', error);
})
.on('data', function (data) {
// decompressed data
console.log('Decompressed chunck Recived:' + data.length, ': Total downloaded:', total_bytes_read)
total_bytes_read += data.length;
if (total_bytes_read >= MAX_SIZE) {
//TODO: handle exceeds max size event
console.error("Request exceeds max size.");
throw new Error('Request exceeds max size'); //stop
}
})
.on('response', function (response) {
response.on('data', function (chunk) {
//compressed data
console.log('Compressed chunck Recived:' + chunk.length, ': Total downloaded:', total_bytes_read)
});
})
.on('end', function () {
console.log('Request completed! Total size downloaded:', total_bytes_read)
});
注意: 如果服务器没有压缩响应,但您仍然使用gzip选项/解压缩,则解压缩块和原始块将相等。因此,您可以从解压缩的/压缩的块中进行限制检查。但是,如果响应已经压缩,您应该检查解压缩块的大小限制。
2-如果响应未经过压缩,则无需使用gzip选项进行解压缩。
request
.get(URL)
.on('error', function (error) {
//TODO: error handling
console.error('ERROR::', error);
})
.on('response', function (response) {
response.on('data', function (chunk) {
//compressed data
console.log('Recived chunck:' + chunk.length, ': Total downloaded:', total_bytes_read)
total_bytes_read += chunk.length;
if (total_bytes_read >= MAX_SIZE) {
//TODO: handle exceeds max size event
console.error("Request as it exceds max size:")
throw new Error('Request as it exceds max size');
}
console.log("...");
});
})
.on('end', function () {
console.log('Request completed! Total size downloaded:', total_bytes_read)
});
request
包时,也可以使用data
事件。我已经进行了测试,并且对我来说效果很好。var request = require("request");
var size = 0;
const MAX_SIZE = 200;
request
.get('http://google.com/')
.on('data', function(buffer){
// decompressed data as it is received
size += buffer.length;
if (size > MAX_SIZE) {
console.log("Aborting this request as it exceeds max size")
this.abort();
}
console.log("data coming");
}).on('end', function() {
console.log('ending request')
})
.on('response', function (response) {
console.log(response.statusCode) // 200
console.log(response.headers['content-type']) // 'image/png'
response.on('data', function (data) {
// compressed data as it is received
console.log('received ' + data.length + ' bytes of compressed data')
// you can size and abort here also if you want.
})
});
你可以在获取压缩数据或获取未压缩数据的两个地方进行大小检查(基于https://www.npmjs.com/package/request给出的示例)。
.on(data)
来实现。如果您想要头部信息,可以从响应中获取它们,还可以检查content-length
头部并且不开始分块传输。这是axios参考文献中关于maxContentLength
的定义://maxContentLength
定义了允许的http响应内容的最大大小maxContentLength:2000。这就是axios处理maxContentLength
的方式。var responseBuffer = [];
stream.on('data', function handleStreamData(chunk) {
responseBuffer.push(chunk);
// make sure the content length is not over the maxContentLength if specified
if (config.maxContentLength > -1 && Buffer.concat(responseBuffer).length > config.maxContentLength) {
reject(createError('maxContentLength size of ' + config.maxContentLength + ' exceeded',
config, null, lastRequest));
}
});
部分 request
等价
var request = require("request");
const MAX_CONTENT_LENGTH = 10000000;
var receivedLength = 0;
var req = request.get('http://de.releases.ubuntu.com/xenial/ubuntu-16.04.3-desktop-amd64.iso')
.on('response', (response) => {
if (response.headers['content-length'] && response.headers['content-length'] > MAX_CONTENT_LENGTH) {
console.log("max content-length exceeded")
req.abort();
}
})
.on('data', (str) => {
receivedLength += str.length;
if (receivedLength > MAX_CONTENT_LENGTH) {
console.log("max content-length exceeded")
req.abort();
}
})
maxContentLength
。编辑答案并添加了axios的参考资料。 - Stamos