So holen Sie Daten aus einer http-Abrufanforderung von Node.js.

81

Ich versuche, meine Funktion dazu zu bringen, die http get-Anfrage zurückzugeben. Was auch immer ich tue, es scheint im? Scope? Verloren zu sein. Ich bin neu bei Node.js, daher wäre jede Hilfe dankbar

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);
}
Daryl Rodrigo
quelle

Antworten:

117

Natürlich kehren Ihre Protokolle zurück undefined: Sie melden sich an, bevor die Anforderung abgeschlossen ist. Das Problem ist nicht der Umfang, sondern die Asynchronität .

http.requestist asynchron, deshalb wird ein Rückruf als Parameter verwendet. Tun Sie, was Sie im Rückruf tun müssen (den, an den Sie übergeben 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();
Denys Séguret
quelle
10
Ich würde empfehlen, die Chunks in ein Array zu verschieben und am Ende join ('') zu verwenden. Das wird Probleme vermeiden, wenn es viele Daten gibt
Eric
Wie erhalte ich den HTTP-Antwortcode der Antwort (200 oder 404 usw.)? Gibt es eine Dokumentation zu den Schlüsselwörtern 'on' (response.on), 'data' und 'end'? Sind das Schlüsselwörter? Hier scheint es nichts zu geben: nodejs.org/api/http.html#http_class_http_serverresponse
Tyler Durden
@ TylerDurden statusCodeist eine Eigenschaft des Antwortobjekts . Ich konnte auch keine richtige Dokumentation für das ServerResponseObjekt finden, nur Beispiele in den Dokumenten für die getund requestMethoden.
Phoca
1
Aber das macht den Code chaotisch! Warum ist Javascript so gestaltet?
Daniel
@ Daniel Es gibt jetzt Möglichkeiten, das asynchrone Ereignismodell zu verarbeiten: Versprechen und asynchron / warten.
Denys Séguret
15

Kürzeres Beispiel mit http.get:

require('http').get('http://httpbin.org/ip', (res) => {
    res.setEncoding('utf8');
    res.on('data', function (body) {
        console.log(body);
    });
});
Oded Breiner
quelle
Dieses Beispiel ist so kurz wie möglich und wird immer noch ausgeführt. Dies setzt eine gute URL und eine kleine Antwort voraus. Ich bevorzuge die http-Beispiele, die die Datenantwort aufteilen, das Antwortereignis verwenden endund das Anforderungsereignis verwenden errror.
dturvene
2
Diese Antwort ist angesichts der gestellten Frage nicht kontextbezogen. Außerdem warten Sie nicht explizit auf das, error event was ausgelöst wird, wenn die Verbindung unterbrochen wird, während die Anforderung ausgeführt wird, oder wenn während der Übertragung andere Probleme auftreten.
rags2riches
9

von learnyounode:

var http = require('http')  

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

'options' ist die Host- / Pfadvariable

ezchx
quelle
danke, habe überall nach einem einfachen Beispiel gesucht und jeder, den ich gefunden habe, hat ein halbes Dutzend neuer Konzepte auf mich geworfen. Dies hat gerade dargelegt, wie das http.get () schön und einfach funktioniert. Ausgezeichnet!
NickW
8

Einfaches Arbeitsbeispiel für eine HTTP-Anforderung unter Verwendung eines Knotens.

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();
    });
}
smsivaprakaash
quelle
1
Danke fürs Teilen !! Dies war das eindeutige Beispiel mit Rückgabedaten ohne Verwendung von console.log.
Altieres de Matos
6

von 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)
    }))
})
Elise Chant
quelle
3

Dies ist meine Lösung, obwohl Sie mit Sicherheit viele Module verwenden können, die Ihnen das Objekt als Versprechen oder ähnliches geben. Wie auch immer, Sie haben einen weiteren Rückruf verpasst

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

irgendwo anders

getData(function(data){
// YOUR CODE HERE!!!
})
ackuser
quelle
Dies scheint nicht zu funktionieren, da callbackData () nicht als Funktion definiert ist.
Hugo Koopmans
1

Ich denke, es ist zu spät, um diese Frage zu beantworten, aber ich hatte kürzlich das gleiche Problem. Mein Anwendungsfall bestand darin, die paginierte JSON-API aufzurufen, alle Daten aus jeder Paginierung abzurufen und an ein einzelnes Array anzuhängen.

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

Wie @ackuser erwähnt, können wir ein anderes Modul verwenden, aber in meinem Anwendungsfall musste ich den Knoten verwenden https. Ich hoffe, das hilft anderen.

Vaibhav Rai
quelle
1
Danke Alter, ich bin in die gleiche Situation geraten wie Sie. Es ist schade, dass wir die nur httpsfür die Ausgabe von https-Anfragen verwenden können.
Kenshinji