Як отримати дані із запиту на отримання Node.js http


83

Я намагаюся отримати мою функцію для повернення запиту отримання http, однак, що б я не робив, це, здається, загубиться в? Сфері ?. Я кинув новачок у 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 ('') в кінці. Це дозволить уникнути проблем, якщо даних буде багато
Ерік

Як отримати код відповіді HTTP відповіді (200 або 404 тощо)? Чи є документація щодо ключового слова 'on' (response.on), 'data' та 'end'? Це ключові слова? Здається, тут нічого немає: nodejs.org/api/http.html#http_class_http_serverresponse
Тайлер

@TylerDurden statusCode- це властивість об'єкта відповіді. Я також не міг знайти належну документацію для ServerResponseоб'єкта, лише приклади в документації для методів getі request.
Фока

1
Але це робить код безладним! Чому javascript розроблений саме так?
Даніель

@Daniel Зараз є засоби для обробки асинхронної моделі подій: Promises та async / await.
Denys 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-адресу та невелику відповідь. Я віддаю перевагу прикладам http, які розділяють відповідь на дані, використовують endподію відповіді та використовують errrorподію запиту .
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 de Matos,

9

від learnnyounode:

var http = require('http')  

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

'options' - змінна хост / шлях


спасибі, шукав простий приклад, і кожен, кого я знайшов, кинув мені півдюжини нових концепцій. Тут якраз було викладено, як http.get () працює приємно і просто. Відмінно!
NickW

6

від learnnyounode:

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

Це моє рішення, хоча, безсумнівно, ви можете використовувати багато модулів, які надають вам об’єкт як обіцянку або подібне. У будь-якому випадку, вам не вистачало чергового зворотного дзвінка

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

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
Дякую, чувак, я потрапив у таку ж ситуацію, як і ти, це відмовно, ми можемо використовувати лише httpsдля надсилання https-запиту.
kenshinji
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.