Где тело в ответе http.get nodejs?

Я читаю документы по адресу http://nodejs.org/docs/v0.4.0/api/http.html#http.request, но по какой-то причине я не могу найти фактический атрибут body/data на возвращаемом завершенном объекте ответа.

> var res = http.get({host:'www.somesite.com', path:'/'})

> res.finished
true

> res._hasBody
true

Он закончил (http.get делает это для вас), поэтому у него должен быть какой-то контент. Но нет ни тела, ни данных, и я не могу его прочитать. Где тело скрывается?

Ответ 1

Редактировать: отвечать на себя через 6 лет

Ключевое слово await - лучший способ справиться с этим, избегая обратных вызовов и .then()

Вам также потребуется использовать HTTP-клиент, который возвращает Promises. http.get() все еще возвращает объект Request, так что это не сработает. Вы можете использовать fetch, но superagent - это зрелый HTTP-клиент, который имеет более разумные значения по умолчанию, включая запрос более простой строковой кодировки, правильное использование типов mime, JSON по умолчанию и другие общие функции HTTP-клиента. await будет ждать, пока Promise будет иметь значение - в этом случае, ответ HTTP!

const superagent = require('superagent');

(async function(){
  const response = await superagent.get('https://www.google.com')
  console.log(response.text)
})();

Используя wait, управление просто переходит к следующей строке, как только обещание, возвращаемое superagent.get() имеет значение.

Ответ 2

http.request docs содержит пример того, как получить тело ответа посредством обработки события data:

var options = {
  host: 'www.google.com',
  port: 80,
  path: '/upload',
  method: 'POST'
};

var req = http.request(options, function(res) {
  console.log('STATUS: ' + res.statusCode);
  console.log('HEADERS: ' + JSON.stringify(res.headers));
  res.setEncoding('utf8');
  res.on('data', function (chunk) {
    console.log('BODY: ' + chunk);
  });
});

req.on('error', function(e) {
  console.log('problem with request: ' + e.message);
});

// write data to request body
req.write('data\n');
req.write('data\n');
req.end();

http.get делает то же самое, что и http.request, за исключением того, что он автоматически вызывает req.end().

var options = {
  host: 'www.google.com',
  port: 80,
  path: '/index.html'
};

http.get(options, function(res) {
  console.log("Got response: " + res.statusCode);

  res.on("data", function(chunk) {
    console.log("BODY: " + chunk);
  });
}).on('error', function(e) {
  console.log("Got error: " + e.message);
});

Ответ 3

Я также хочу добавить, что http.ClientResponse, возвращаемый http.get(), имеет событие end, так что вот еще один способ получить ответ тела:

var options = {
  host: 'www.google.com',
  port: 80,
  path: '/index.html'
};

http.get(options, function(res) {
  var body = '';
  res.on('data', function(chunk) {
    body += chunk;
  });
  res.on('end', function() {
    console.log(body);
  });
}).on('error', function(e) {
  console.log("Got error: " + e.message);
}); 

Ответ 4

Если вы хотите использовать .get, вы можете сделать это следующим образом

http.get(url, function(res){
    res.setEncoding('utf8');
    res.on('data', function(chunk){
        console.log(chunk);
    });

});

Ответ 5

Вам нужно добавить слушателя к запросу, потому что node.js работает так же асинхронно:

request.on('response', function (response) {
  response.on('data', function (chunk) {
    console.log('BODY: ' + chunk);
 });
});

Ответ 6

Событие data запускается несколько раз с "кусками" тела при их загрузке и end событием, когда загружаются все куски.

Теперь, когда Node поддерживает Promises, я создал простую оболочку для возврата конкатенированных кусков через Promise:

const httpGet = url => {
  return new Promise((resolve, reject) => {
    http.get(url, res => {
      res.setEncoding('utf8');
      let body = ''; 
      res.on('data', chunk => body += chunk);
      res.on('end', () => resolve(body));
    }).on('error', reject);
  });
};

Вы можете вызвать его из функции async с помощью:

const body = await httpGet('http://www.somesite.com');

Ответ 7

Игла также хороша, вот пример, который использует needle module

var needle = require('needle');

needle.get('http://www.google.com', function(error, response) {
  if (!error && response.statusCode == 200)
    console.log(response.body);
});

Ответ 8

Вы не можете получить тело ответа от возвращаемого значения http.get().

http.get() не возвращает объект ответа. Он возвращает объект запроса ( http.clientRequest). Таким образом, нет никакого способа получить тело ответа от возвращаемого значения http.get().

Я знаю, что это старый вопрос, но чтение документации, на которую вы ссылались, показывает, что это было так, даже когда вы ее разместили.

Ответ 9

Часть кофе здесь:

# My little helper
read_buffer = (buffer, callback) ->
  data = ''
  buffer.on 'readable', -> data += buffer.read().toString()
  buffer.on 'end', -> callback data

# So request looks like
http.get 'http://i.want.some/stuff', (res) ->
  read_buffer res, (response) ->
    # Do some things with your response
    # but don't do that exactly :D
    eval(CoffeeScript.compile response, bare: true)

И скомпилированный

var read_buffer;

read_buffer = function(buffer, callback) {
  var data;
  data = '';
  buffer.on('readable', function() {
    return data += buffer.read().toString();
  });
  return buffer.on('end', function() {
    return callback(data);
  });
};

http.get('http://i.want.some/stuff', function(res) {
  return read_buffer(res, function(response) {
    return eval(CoffeeScript.compile(response, {
      bare: true
    }));
  });
});