Bir nodejs http.get yanıtında gövde nerede?


187

Http://nodejs.org/docs/v0.4.0/api/http.html#http.request adresindeki dokümanları okuyorum , ancak bazı nedenlerden dolayı aslında body / data özelliğini bulamıyorum döndürülen bitmiş yanıt nesnesinde.

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

> res.finished
true

> res._hasBody
true

Tamamlandı (http.get bunu sizin için yapar), bu yüzden bir çeşit içeriğe sahip olmalıdır. Ama beden yok, veri yok ve ondan okuyamıyorum. Beden nerede saklanıyor?


7
Cevapların hiçbiri ne zaman bileceksiniz nasıl söz yana dataolayların yapılır .. var senin resiçin dinlemek "end"( nodejs.org/docs/latest/api/http.html#event_end_ )
SooDesuNe

Yanıtlar:


172

http.request dokümanları, işleme dataolayıyla yanıt gövdesinin nasıl alınacağına ilişkin örnek içerir :

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 , req.end()otomatik olarak çağırması dışında http.request ile aynı şeyi yapar .

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

15
Nedense res.setEncoding('utf8');http.get örneğine eklemek zorunda kaldım. Aksi takdirde chunkdeğişkente HTML alamadım .
SSH Bu

1
@SSHBunun nedeni, ham veri içeren Arabellek nesneleridir. Onlardan dizeler istiyorsanız, chunk.toString () yöntemini de kullanabilirsiniz, isteğe bağlı olarakString ve kodlamaya geçebilirsiniz. Bununla birlikte, setEncoding muhtemelen daha verimlidir.
Aralık'ta

14
"data" etkinliği birden çok kez çağrılabilir ve içeriği parça parça alırsınız. Örnek, bunların nasıl yapıştırılacağını göstermez.
Andrej

4
@tfmontague. Kabul! Şaşırtıcı ... en temelde kusurlu olan bir cevap için çok fazla oy.
Güneşli

@tfmontague: POST requests typically use a response body, not GET.Gönderme isteğinin bir gövdesi var ve GET isteğinde bulunmuyor, ancak bir GET yanıtının bir gövdesi olabilir.
Cyrbil

135

Ayrıca http.ClientResponsedöndürülen tarafından http.get()bir endolay olduğunu eklemek istiyorum , bu yüzden burada vücut yanıtı almak başka bir yoludur:

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

13
Bunun için teşekkürler! 'Bitiş' olayı benim için çok önemliydi, çünkü tepki gövdesini parçalardan ziyade bir bütün olarak işlemek zorunda kaldım.
Daniel Gruszczyk

http.ClientResponsehttp.get() http.ClientRequesthem geçerli belgelere hem de orijinal posterle bağlantılı belgelere göre döndürülmez .
Vince

54

Düzenleme: 6 yıl sonra kendine cevap

Bekliyoruz kelime geri aramalar kaçınarak, bir HTTP isteği bir yanıt almak için en iyi yoldur ve.then()

Ayrıca Promises döndüren bir HTTP istemcisi kullanmanız gerekir. http.get()yine de bir Request nesnesi döndürür, böylece çalışmaz. Kullanabilirsiniz fetch, ancak superagentdaha basit sorgu dizesi kodlaması, mime türlerini doğru bir şekilde kullanma, varsayılan olarak JSON ve diğer yaygın HTTP istemci özellikleri gibi daha makul varsayılanlara sahip olgun bir HTTP istemcisidir. awaitSözün bir değeri olana kadar bekleyecektir - bu durumda bir HTTP yanıtı!

const superagent = require('superagent');

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

Bekleme özelliğini kullanarak, döndürülen sözün bir değeri olduğunda kontrol basitçe bir sonraki satıra geçersuperagent.get() .


3
Bu orijinal sorunuza cevap vermiyor. Örnek kodunuzda , değil resdönüş değerine ayarlanır . özelliği olmayan bir döndürür . Yanıt nesnesi değil, istek nesnesi. superagent.get()http.get()http.get()http.IncomingMessagetext
Vince

İyi bir nokta Vince Cevabı daha temiz hale getirmek için, Düzenleri destekleyen bir HTTP istemcisi kullanıyorum.
mikemaccana

12

dataOlay Yüklenirken gibi vücudun 'parçaları' ve bir ile birkaç kez ateşlenir endtüm parçalar indirilmiş olay.

Düğüm Promises'ı şimdi desteklerken , bitmiş parçaları bir Promise aracılığıyla döndürmek için basit bir sarmalayıcı oluşturdum:

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

Bir asenkron işlevinden aşağıdakilerle arayabilirsiniz:

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

11

Eğer kullanmak istiyorsanız .get bunu böyle yapabilirsiniz

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

});

2
Diğer örnekler bana, yığın cevabı içeren metin eklemediğimde onaltılı değerlere benzediğini verdi. Kodlamanın ayarlanması aradığım JSON belgesini görüntüledi. Teşekkür ederim!
Collin McGuire

@CollinMcGuire ham veri içeren Arabellek nesneler oldukları için. Onlardan dizeler istiyorsanız chunk.toString(), isteğe bağlı olarak geçirip toStringkodlayabilirsiniz. Bununla birlikte setEncoding, muhtemelen daha verimlidir.
Aralık'ta

6

Node.js şu şekilde eşzamansız çalıştığı için isteğe bir dinleyici eklemeniz gerekir:

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

2

İğne modülü de iyidir, burada needlemodül kullanan bir örnek

var needle = require('needle');

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

0

Kahvenin bir kısmı burada:

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

Ve derlendi

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

Yanıtın gövdesini, dönüş değerinden alamazsınız http.get().

http.get()bir yanıt nesnesi döndürmez. İstek nesnesini ( http.clientRequest) döndürür . Yani, yanıtın gövdesini dönüş değerinden almanın bir yolu yoktur http.get().

Bunun eski bir soru olduğunu biliyorum, ancak bağlantı verdiğiniz belgeleri okumak , bunu yayınladığınızda bile durumun böyle olduğunu gösteriyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.