Итак, в этом (упрощенном) фрагменте кода, когда кто-то попадает на мой сервер узла, я делаю запрос GET на другой веб-сайт и распечатываю заголовок HTML-страницы на консоли. Работает отлично:

var http = require("http");
var cheerio = require('cheerio');

var port = 8081;
s = http.createServer(function (req, res) {
var opts = {
    method: 'GET',
    port: 80,
    hostname: "pwoing.com",
    path: "/"
};
http.request(opts, function(response) {
    console.log("Content-length: ", response.headers['content-length']);
    var str = '';
    response.on('data', function (chunk) {
        str += chunk;
    });
    response.on('end', function() {
        dom = cheerio.load(str);
        var title = dom('title');
        console.log("PAGE TITLE: ",title.html());
    });
}).end();
res.end("Done.");
}).listen(port, '127.0.0.1');

Однако в реальном приложении пользователи могут указать URL-адрес для обращения. Это означает, что мой сервер узла может загружать файлы фильмов размером 20 ГБ или что-то еще. Нехорошо. Заголовок длины содержимого также бесполезен для предотвращения этого, поскольку он передается не всеми серверами. Тогда возникает вопрос:

Как я могу сказать ему, что он должен останавливать запрос GET после того, как, скажем, получены первые 10 КБ?

Ура!

10
BaronVonKaneHoffen 26 Мар 2013 в 15:36
Как насчет проверки типа содержимого / типа пантомимы?
 – 
Amberlamps
26 Мар 2013 в 15:46
Могу ли я предположить, но, как и длина содержимого, это ненадежный индикатор - сервер, к которому я делаю запрос, все еще может отправлять данные любой длины технически. ... как я понимаю! Наверняка должен быть способ просто "повесить трубку" после первых 10К тела.
 – 
BaronVonKaneHoffen
26 Мар 2013 в 15:52
Другой подход, который вы, возможно, захотите рассмотреть, - это использовать потоки и передавать их клиенту по мере их поступления, чтобы не буферизовать весь ответ. docs.nodejitsu.com/articles/advanced/streams/ …
 – 
Hector Correa
26 Мар 2013 в 17:15

1 ответ

Лучший ответ

Вы можете прервать запрос, как только прочитаете достаточно данных:

  http.request(opts, function(response) {
    var request = this;
    console.log("Content-length: ", response.headers['content-length']);
    var str = '';
    response.on('data', function (chunk) {
      str += chunk;
      if (str.length > 10000)
      {
        request.abort();
      }
    });
    response.on('end', function() {
      console.log('done', str.length);
      ...
    });
  }).end();

Это прервет запрос на примерно 10.000 байтах, поскольку данные поступают кусками разного размера.

14
robertklep 26 Мар 2013 в 15:57
Ага! Вот что мне было нужно. Очень признателен :)
 – 
BaronVonKaneHoffen
26 Мар 2013 в 17:26
Не могли бы вы прояснить мне одну вещь? Я проверил, добавив console.log ('something) непосредственно перед "str + = chunk", он регистрируется только один раз, но я уверен, что получаю несколько фрагментов данных, поэтому в этом случае он должен регистрироваться несколько раз .. .
 – 
Devasish
26 Апр 2017 в 14:25
Да, вы этого и ожидали, если только вы не используете тот же код, что и мой ответ, и запрос не будет прерван?
 – 
robertklep
26 Апр 2017 в 14:40