web-dev-qa-db-fra.com

Où est le corps dans une réponse de nodejs http.get?

Je lis les docs sur http://nodejs.org/docs/v0.4.0/api/http.html#http.request , mais pour une raison quelconque, je n'arrive pas à trouver le attribut body/data sur l'objet de réponse renvoyé et terminé. 

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

> res.finished
true

> res._hasBody
true

C'est fini (http.get le fait pour vous), il devrait donc avoir un contenu quelconque. Mais il n'y a pas de corps, pas de données, et je ne peux pas les lire. Où se cache le corps?

160
mikemaccana

Edit: répondre à soi 6 ans plus tard

Le mot clé wait _ est le meilleur moyen de gérer cela, en évitant les rappels et .then().

Vous devrez également utiliser un client HTTP qui renvoie Promises.http.get() renvoie toujours un objet Request, donc cela ne fonctionnera pas. Vous pouvez utiliser fetch, mais superagent est un client HTTP mature qui présente des valeurs par défaut plus raisonnables, notamment un codage de chaîne simple, utilisant correctement les types mime, JSON par défaut et d'autres fonctionnalités client HTTP courantes. await attendra que la promesse ait une valeur - dans ce cas, une réponse HTTP!

const superagent = require('superagent');

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

En utilisant wait, control passe simplement sur la ligne suivante une fois que la promesse retournée par superagent.get() a une valeur.

49
mikemaccana

http.request docs contient un exemple sur la façon de recevoir le corps de la réponse via la gestion de l'événement 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 fait la même chose que http.request sauf qu'il appelle req.end() automatiquement.

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

Je souhaite également ajouter que le http.ClientResponse renvoyé par http.get() a un événement end. Voici donc un autre moyen de recevoir la réponse body:

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

Si vous voulez utiliser .get, vous pouvez le faire comme ceci 

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

});
11
user969714

Vous devez ajouter un écouteur à la demande, car node.js fonctionne comme suit:

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

L'événement data est déclenché plusieurs fois avec des «morceaux» du corps lorsqu'ils sont téléchargés et un événement end lorsque tous les morceaux ont été téléchargés.

Avec Node support Promises now, j'ai créé un wrapper simple pour renvoyer les morceaux concaténés via une promesse:

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

Vous pouvez l'appeler depuis une fonction asynchrone avec:

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

Le module Needle est également bon, voici un exemple qui utilise le module needle 

var needle = require('needle');

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

Vous ne pouvez pas obtenir le corps de la réponse à partir de la valeur de retour http.get().

http.get() ne renvoie pas d'objet de réponse. Il retourne l'objet requête ( http.clientRequest ). Il n'y a donc aucun moyen d'obtenir le corps de la réponse à partir de la valeur de retour de http.get().

Je sais que c’est une vieille question, mais en lisant la documentation à laquelle vous avez accédé montre que c’était le cas même lorsque vous l’aviez publiée.

0
Vince

Une portion de café ici:

# 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)

Et compilé

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
    }));
  });
});
0
18augst