nodejs http.getレスポンスの本文はどこにありますか?


187

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がそれを行います)、何らかのコンテンツが含まれているはずです。しかし、本体もデータもなく、そこから読み取ることはできません。体はどこに隠れていますか?


7
答えのどれもがときあなたが知っているよどのように言及していないので、dataイベントが行われます。..あなたの持っているresために聞く"end"nodejs.org/docs/latest/api/http.html#event_end_
SooDesuNe

回答:


172

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は、req.end()自動的に呼び出すことを除いて、http.requestと同じことを行います。

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
何らかの理由でres.setEncoding('utf8');、http.getの例に追加する必要がありました。それ以外の場合、chunk変数にHTMLが含まれていません。
2013

1
@SSHこれは、それらが生データを含むBufferオブジェクトであったためです。それらから文字列が必要な場合は、chunk.toString()を使用して、オプションでtoStringとエンコーディングを渡すこともできます。つまり、setEncodingの方が効率的です。
skeggse 2013

14
「データ」イベントは複数回呼び出される可能性があり、コンテンツを少しずつ取得します。例では、それらを接着する方法を示していません。
Andrej

4
@tfmontague。同意しました!驚くべきことに...根拠に欠陥のある回答への賛成票が多すぎます。
2015

@tfmontague: POST requests typically use a response body, not GET.Post リクエストには本文がありますが、GET リクエストにはありませんが、GET 応答には本文があります。
Cyrbil、2015年

135

また、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);
}); 

13
それをありがとう!チャンクではなく全体として応答本文を処理する必要があったため、「終了」イベントは私にとって重要でした。
Daniel Gruszczyk 2015年

http.ClientResponsehttp.get() http.ClientRequest現在のドキュメントと元の投稿者がリンクしているドキュメントの両方によると、isはis によって返されません。
Vince

54

編集:6年後の自分への返信

awaitキーワードは、コールバックを避け、HTTPリクエストからレスポンスを取得するための最良の方法であると.then()

また、Promiseを返すHTTPクライアントを使用する必要があります。 http.get()まだRequestオブジェクトを返すため、機能しません。あなたは使うことができfetchますが、superagentデフォルト、および他の一般的なHTTPクライアント機能により、単純なクエリ文字列のエンコーディングを含む、より合理的なデフォルトを特徴と成熟したHTTPクライアントで、適切なMIMEタイプを使用して、JSON。awaitPromiseに値があるまで待機します-この場合、HTTP応答!

const superagent = require('superagent');

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

awaitを使用すると、によって返されるpromiseにsuperagent.get()が設定されると、制御は次の行に渡されます。


3
これは元の質問の答えにはなりません。コード例でresは、はの戻り値に設定され、でsuperagent.get()はありませんhttp.get()。プロパティを持たないをhttp.get()返します。これは応答オブジェクトではなく、要求オブジェクトです。http.IncomingMessagetext
Vince

良い点Vince PromisesをサポートするHTTPクライアントを使用しているので、答えをわかりやすく編集します。
mikemaccana

12

dataイベントは、彼らがダウンロードされるように、本体の「チャンク」とで複数回発射されたendすべてのチャンクがダウンロードされているイベント。

ノードをサポートすると約束し、今、私は約束を通じて連結チャンクを返すために、単純なラッパーを作成しました:

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

あなたは非同期関数からそれを呼び出すことができます:

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

11

.getを使用したい場合は、このようにすることができます

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

});

2
他の例では、チャンク応答にテキストを含めなかった場合に、16進値のように見えました。エンコーディングを設定すると、探していたJSONドキュメントが表示されました。ありがとうございました!
Collin McGuire

@CollinMcGuireは、生データを含むBufferオブジェクトであったためです。それらから文字列が必要な場合はchunk.toString()、オプションで渡しtoString、エンコードすることもできます。そうは言っても、setEncodingおそらくもっと効率的です。
skeggse 2013

6

node.jsは次のように非同期で動作するため、リクエストにリスナーを追加する必要があります。

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

2

針モジュールも良いです、これはneedleモジュールを使用する例です

var needle = require('needle');

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

0

ここにコーヒーの一部:

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

0

の戻り値から応答の本文を取得することはできませんhttp.get()

http.get()応答オブジェクトを返しません。リクエストオブジェクト(http.clientRequest)を返します。したがって、の戻り値から応答の本文を取得する方法はありませんhttp.get()

私はそれが古い質問であることを知っていますが、リンクしたドキュメントを読むと投稿したときでもこれが事実であることがわかります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.