我想设置simplified HTTP request() client package以中止下载太大的HTTP资源。
让我们假设request()设置为下载网址,资源大小为5千兆字节。我想请求()在10MB后停止下载。通常,当请求得到答案时,它会获取所有HTTP头和后面的所有内容。操作数据后,您已经拥有了所有下载的数据。
在axios中,有一个名为maxContentLength的参数,但我找不到与request()相似的任何内容。
我还必须提一下,我不是为了捕获错误,而是至少只下载标题和资源的开头。
答案 0 :(得分:4)
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选项 为真。
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)
});
NB:如果服务器没有压缩响应,但您仍然使用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)
});
答案 1 :(得分:2)
在这种data
包的情况下,您也可以使用request
事件。我在下面进行了测试,它对我来说很好用
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给出的示例)
答案 2 :(得分:1)
正如@Jackthomson在第一条评论的回答中指出的那样,可以使用.on(data)
来完成。如果你想要标题,你可以从响应中获取它们,你也可以检查content-length
标题而不是开始分块。
来自axios参考。
//
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();
}
})