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

时间:2017-11-22 08:59:47

标签: node.js http post http-post

我想设置simplified HTTP request() client package以中止下载太大的HTTP资源。

让我们假设request()设置为下载网址,资源大小为5千兆字节。我想请求()在10MB后停止下载。通常,当请求得到答案时,它会获取所有HTTP头和后面的所有内容。操作数据后,您已经拥有了所有下载的数据。

在axios中,有一个名为maxContentLength的参数,但我找不到与request()相似的任何内容。

我还必须提一下,我不是为了捕获错误,而是至少只下载标题和资源的开头。

3 个答案:

答案 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();
        }
    })