2017-11-22 40 views
5

Tôi muốn thiết lập số simplified HTTP request() client package để hủy tải xuống tài nguyên HTTP quá lớn.Làm cách nào để hạn chế phản hồi độ dài nội dung của yêu cầu HTTP đơn giản trong nút?

Hãy tưởng tượng yêu cầu() được thiết lập để tải xuống url và kích thước tài nguyên là 5 Gigabyte. Tôi muốn yêu cầu() ngừng tải xuống sau 10MB. Thông thường, khi yêu cầu nhận được câu trả lời, nó sẽ nhận tất cả các tiêu đề HTTP và mọi thứ phía sau. Khi bạn thao tác dữ liệu, bạn đã có tất cả dữ liệu đã tải xuống.

Trong trục, có tham số được gọi là maxContentLength nhưng tôi không thể tìm thấy bất kỳ điều gì tương tự cho yêu cầu().

Tôi cũng phải đề cập đến, tôi không bắt lỗi nhưng chỉ tải xuống ít nhất tiêu đề và phần đầu của tài nguyên.

+1

Điều này có hữu ích không? - https://stackoverflow.com/questions/15636095/how-to-limit-response-length-with-http-request-in-node-js – Jackthomson

+0

Cảm ơn bạn nhưng tôi sử dụng một gói được gọi là yêu cầu và nó được đơn giản hóa phiên bản của yêu cầu HTTP nodejs. Tuy nhiên, câu trả lời của bạn có thể hữu ích vì nếu tôi không nhận được câu trả lời, tôi sẽ phải thay thế gói yêu cầu bằng yêu cầu HTTP từ nút. –

+1

Bạn đang nói abou gói này - https://www.npmjs.com/package/request - Nếu như vậy bạn không thể sử dụng nó chính xác như câu trả lời được liên kết ở trên, thư viện yêu cầu này vẫn trả về cùng một đối tượng phản hồi để nó có các nguyên mẫu trên và bạn có thể móc vào nó chỉ là cùng một quyền? Hoặc thư viện này có xóa chức năng đó không? Thư viện này dường như làm cho quá trình dễ dàng hơn một chút với một số cú pháp đẹp .. ở cốt lõi của nó nó chỉ trả về một yêu cầu nút và đối tượng phản hồi – Jackthomson

Trả lời

3
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 - Nếu phản hồi từ máy chủ được nén gzip, bạn nên bật tùy chọn gzip. https://github.com/request/request#examples Để tương thích ngược, nén phản hồi không được hỗ trợ bởi mặc định. Để chấp nhận phản hồi nén gzip, hãy đặt tùy chọn gzip thành 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) 
    }); 

NB: Nếu máy chủ không nén phản ứng nhưng bạn vẫn sử dụng gzip tùy chọn/giải nén, sau đó các đoạn giải nén & các đoạn ban đầu sẽ bình đẳng.Do đó bạn có thể thực hiện kiểm tra Giới hạn theo cách (từ đoạn đã nén/nén) Tuy nhiên nếu đáp ứng được nén , bạn nên kiểm tra giới hạn kích thước của đoạn đã giải nén

2 - nếu phản hồi không bị nén cần tùy chọn gzip để giải nén

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

Bạn cũng có thể sử dụng sự kiện data trong trường hợp này là gói request. Tôi đã thử nghiệm dưới đây và nó làm việc tốt cho tôi

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

Có hai nơi mà bạn có thể thực hiện việc kiểm tra kích thước, hoặc là nơi bạn có được dữ liệu nén hoặc trong trường hợp bạn nhận được dữ liệu không nén (dựa trên ví dụ đưa ra ở https://www.npmjs.com/package/request)

1

Khi @Jackthomson chỉ ra trong câu trả lời của bình luận đầu tiên, bạn có thể thực hiện bằng cách sử dụng .on(data) Nếu bạn muốn tiêu đề bạn có thể đưa họ phản hồi và bạn cũng có thể kiểm tra tiêu đề content-length và không bắt đầu chunking.

Từ tham chiếu trục.

// maxContentLength xác định kích thước tối đa của http phản ứng nội dung cho phép maxContentLength: 2000,

Đây là cách Axios xử lý 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)); 
      } 
     }); 

phần request tương đương

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(); 
     } 
    }) 
+0

tiêu đề nội dung có độ dài là tổng kích thước của tệp chứ không phải từng phần riêng lẻ. OP muốn ngừng tải xuống sau khi đạt đến mức tối đa. – Mehari

+0

Tôi đồng ý. OP cũng đề cập đến các trục và 'maxContentLength'. Chỉnh sửa câu trả lời và thêm tham chiếu từ các trục – Stamos

Các vấn đề liên quan