如何限制节点中简化HTTP请求的内容长度响应?

我想设置简化的HTTP请求()客户端软件包来中止太大的HTTP资源的下载。

假设request()被设置为下载一个url,并且资源大小是5千兆字节。 我想request()在10MB之后停止下载。 通常,当请求获得答案时,它会获得所有的HTTP标题以及后面的所有内容。 一旦你操作数据,你已经有了所有的下载数据。

在axios中,有一个名为maxContentLength的参数,但是我找不到任何类似于request()的东西。

我还必须提及,我不是要捕获一个错误,而只是至less下载头文件和资源的开始。

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) }); 

在这种情况下,您也可以使用data事件。 我testing下面,它对我工作得很好

 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中的示例)

正如@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(); } })