如何从Node.js http获取请求中获取数据


82

我正在尝试让我的函数返回http get请求,但是,无论如何,它似乎在?scope中丢失了。我对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);
}

Answers:


118

当然,您的日志会返回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
泰勒·

@TylerDurdenstatusCode是响应对象的属性。我也找不到该ServerResponse对象的适当文档,仅是getandrequest方法的文档中的示例。
Phoca

1
但这会使代码混乱!为什么用javascript这样设计?
丹尼尔(Daniel)

@Daniel现在有处理异步事件模型的工具:Promises和async / await。
DenysSéguret18年

15

使用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

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

9

使用节点的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

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提到的那样,我们可以使用其他模块,但是在我的用例中,我必须使用node https。希望这对别人有帮助。


1
谢谢花花公子,我遇到了和你一样的情况,很糟糕,我们只能使用https发出https请求。
kenshinji '19
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.