Как получить данные из HTTP-запроса на получение Node.js


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методов.
Phoca

1
Но это делает код беспорядочным! Почему javascript устроен так?
Daniel

@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

от Learnyounode:

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

от 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

Это мое решение, хотя вы наверняка можете использовать множество модулей, которые передают вам объект как обещание или что-то подобное. В любом случае, вам не хватало другого обратного вызова

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 () не определен как функция?
Хьюго Купманс

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.