Node.js httpgetリクエストからデータを取得する方法


83

関数でhttpgetリクエストを返そうとしていますが、何をしても「スコープ」で失われるようです。私はNode.jsを初めて使用するので、助けていただければ幸いです。

function getData(){
  var http = require('http');
  var str = '';

  var options = {
        host: 'www.random.org',
        path: '/integers/?num=1&min=1&max=10&col=1&base=10&format=plain&rnd=new'
  };

  callback = function(response) {

        response.on('data', function (chunk) {
              str += chunk;
        });

        response.on('end', function () {
              console.log(str);
        });

        //return str;
  }

  var req = http.request(options, callback).end();

  // These just return undefined and empty
  console.log(req.data);
  console.log(str);
}

回答:


119

もちろん、ログは返さundefinedれます。リクエストが完了する前にログを記録します。問題はスコープではなく、非同期性です。

http.requestは非同期であるため、パラメータとしてコールバックを取ります。コールバック(渡すものresponse.end)で行う必要があることを実行します。

callback = function(response) {

  response.on('data', function (chunk) {
    str += chunk;
  });

  response.on('end', function () {
    console.log(req.data);
    console.log(str);
    // your code here if you want to use the results !
  });
}

var req = http.request(options, callback).end();

10
チャンクを配列にプッシュし、最後にjoin( '')を使用することをお勧めします。データが多い場合は問題を回避できます
Eric

応答のHTTP応答コード(200または404など)を取得するにはどうすればよいですか?キーワード「on」(response.on)、「data」、「end」に関するドキュメントはありますか?これらのキーワードはありますか?ここには何もないようです:nodejs.org/api/http.html#http_class_http_serverresponse
Tyler

@TylerDurdenstatusCodeは、応答オブジェクトのプロパティです。私はのための適切な文書を見つけることができませんでしたServerResponse、どちらかのためのドキュメントでちょうど例のオブジェクトをgetしてrequestメソッドを。
ゴマフアザラシ2017年

1
しかし、これはコードを乱雑にします!なぜjavascriptはこのように設計されているのですか?
ダニエル

@Daniel非同期イベントモデルを処理する機能が追加されました:Promisesおよびasync / await。
デニス・Séguret

16

http.getを使用した短い例:

require('http').get('http://httpbin.org/ip', (res) => {
    res.setEncoding('utf8');
    res.on('data', function (body) {
        console.log(body);
    });
});

この例は、取得して実行できる限り短いものです。これは、良好なURLと小さな応答を前提としています。私は、データ応答をチャンクし、応答endイベントを使用し、要求errrorイベントを使用するhttpの例を好みます。
dturvene

2
尋ねられた質問を考えると、この答えは文脈から外れています。それに加えて、error event リクエストの進行中に接続が失われた場合、または送信中に他の問題が発生した場合にトリガーされるを明示的にリッスンしていません。
rags2riches

10

ノードを使用したHttpリクエストの簡単な作業例。

const http = require('https')

httprequest().then((data) => {
        const response = {
            statusCode: 200,
            body: JSON.stringify(data),
        };
    return response;
});
function httprequest() {
     return new Promise((resolve, reject) => {
        const options = {
            host: 'jsonplaceholder.typicode.com',
            path: '/todos',
            port: 443,
            method: 'GET'
        };
        const req = http.request(options, (res) => {
          if (res.statusCode < 200 || res.statusCode >= 300) {
                return reject(new Error('statusCode=' + res.statusCode));
            }
            var body = [];
            res.on('data', function(chunk) {
                body.push(chunk);
            });
            res.on('end', function() {
                try {
                    body = JSON.parse(Buffer.concat(body).toString());
                } catch(e) {
                    reject(e);
                }
                resolve(body);
            });
        });
        req.on('error', (e) => {
          reject(e.message);
        });
        // send the request
       req.end();
    });
}

1
共有してくれてありがとう!これは、console.logを使用せずにデータを返すユニークなサンプルでした。
Altieres deMatos20年

9

learnyounodeから:

var http = require('http')  

http.get(options, function (response) {  
  response.setEncoding('utf8')  
  response.on('data', console.log)  
  response.on('error', console.error)  
})

「オプション」はホスト/パス変数です


おかげで、簡単な例を探し回っていましたが、見つけたものはすべて、半ダースの新しい概念を私に投げかけました。これは、http.get()がどのようにうまく機能するかを示したものです。優秀な!
NickW

6

learnyounodeから:

var http = require('http')
var bl = require('bl')

http.get(process.argv[2], function (response) {
    response.pipe(bl(function (err, data) {
        if (err)
            return console.error(err)
        data = data.toString()
        console.log(data)
    }))
})

3

これは私の解決策ですが、確かに、promiseなどとしてオブジェクトを提供する多くのモジュールを使用できます。とにかく、あなたは別のコールバックを逃していました

function getData(callbackData){
  var http = require('http');
  var str = '';

  var options = {
        host: 'www.random.org',
        path: '/integers/?num=1&min=1&max=10&col=1&base=10&format=plain&rnd=new'
  };

  callback = function(response) {

        response.on('data', function (chunk) {
              str += chunk;
        });

        response.on('end', function () {
              console.log(str);
          callbackData(str);
        });

        //return str;
  }

  var req = http.request(options, callback).end();

  // These just return undefined and empty
  console.log(req.data);
  console.log(str);
}

何処か別の場所

getData(function(data){
// YOUR CODE HERE!!!
})

callbackData()が関数として定義されていないため、これは機能しないようです。
Hugo Koopmans 2017

1

この質問に答えるには遅すぎると思いますが、最近同じ問題に直面しました。私のユースケースは、ページ付けされたJSON APIを呼び出し、各ページ付けからすべてのデータを取得して、単一の配列に追加することでした。

const https = require('https');
const apiUrl = "https://example.com/api/movies/search/?Title=";
let finaldata = [];
let someCallBack = function(data){
  finaldata.push(...data);
  console.log(finaldata);
};
const getData = function (substr, pageNo=1, someCallBack) {

  let actualUrl = apiUrl + `${substr}&page=${pageNo}`;
  let mydata = []
  https.get(actualUrl, (resp) => {
    let data = '';
    resp.on('data', (chunk) => {
        data += chunk;
    });
    resp.on('end', async () => {
        if (JSON.parse(data).total_pages!==null){
          pageNo+=1;
          somCallBack(JSON.parse(data).data);
          await getData(substr, pageNo, someCallBack);
        }
    });
  }).on("error", (err) => {
      console.log("Error: " + err.message);
  });
}

getData("spiderman", pageNo=1, someCallBack);

@ackuserが述べたように、他のモジュールを使用できますが、私のユースケースではノードを使用する必要がありましたhttps。これが他の人を助けることを願っています。


1
おかげで、私はあなたと同じ状況に遭遇しました、それは私たちがhttpshttpsリクエストを発行するためにのみ使用できるのは残念です。
kenshinji
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.