Cách lấy dữ liệu ra khỏi http nhận yêu cầu của Node.js


82

Tôi đang cố lấy chức năng của mình để trả lại yêu cầu nhận http, tuy nhiên, bất cứ điều gì tôi làm, nó dường như bị lạc trong phạm vi? Tôi chưa quen với Node.js nên mọi sự giúp đỡ sẽ được đánh giá cao

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

Câu trả lời:


118

Tất nhiên nhật ký của bạn trở lại undefined: bạn đăng nhập trước khi yêu cầu được thực hiện. Vấn đề không phải là phạm vi mà là sự không đồng bộ .

http.requestlà không đồng bộ, đó là lý do tại sao nó nhận một tham số gọi lại. Làm những gì bạn phải làm trong lệnh gọi lại (cuộc gọi mà bạn chuyển đến 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
Tôi khuyên bạn nên đẩy các phần vào một mảng và sau đó sử dụng join (''). Điều đó sẽ tránh được vấn đề nếu có nhiều dữ liệu
Eric

Làm cách nào để nhận mã phản hồi HTTP của phản hồi (200 hoặc 404, v.v.)? Có tài liệu nào về từ khoá 'on' (response.on), 'data' và 'end' không? Đây là những từ khóa? Dường như không có gì ở đây: nodejs.org/api/http.html#http_class_http_serverresponse
Tyler Durden

@TylerDurden statusCodelà một thuộc tính của đối tượng phản hồi. Tôi cũng không thể tìm thấy tài liệu thích hợp cho ServerResponseđối tượng, chỉ là các ví dụ trong tài liệu về phương thức getrequest.
Phoca

1
Nhưng điều này làm cho mã lộn xộn! Tại sao javascript được thiết kế như thế này?
Daniel

@Daniel Hiện có các phương tiện để xử lý mô hình sự kiện không đồng bộ: Promises và async / await.
Denys Séguret

15

Ví dụ ngắn hơn bằng cách sử dụng http.get:

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

Ví dụ này ngắn nhất bạn có thể lấy và vẫn chạy. Điều này giả định một url tốt và phản hồi nhỏ. Tôi thích các ví dụ http phân đoạn phản hồi dữ liệu, sử dụng endsự kiện phản hồi và sử dụng errrorsự kiện yêu cầu .
dturvene

2
Câu trả lời này nằm ngoài ngữ cảnh cho câu hỏi được hỏi. Bên cạnh đó, bạn không lắng nghe rõ ràng error event điều gì sẽ được kích hoạt nếu kết nối bị mất trong khi yêu cầu đang được thực hiện hoặc nếu có bất kỳ sự cố nào khác xảy ra trong quá trình truyền.
rags2riches

9

từ learningnyounode:

var http = require('http')  

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

'options' là biến máy chủ / đường dẫn


cảm ơn, tôi đã xem xét tất cả các ví dụ đơn giản và mỗi một ví dụ tôi tìm thấy đều ném vào tôi nửa tá khái niệm mới. Điều này chỉ ra cách http.get () hoạt động tốt và đơn giản. Thông minh!
NickW

9

Làm việc đơn giản Ví dụ về yêu cầu Http sử dụng nút.

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
Cảm ơn vì đã chia sẻ !! Đây là mẫu duy nhất có dữ liệu trả về mà không cần sử dụng console.log.
Altieres de Matos

6

từ learningnyounode:

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

Đây là giải pháp của tôi, mặc dù chắc chắn bạn có thể sử dụng nhiều mô-đun cung cấp cho bạn đối tượng như một lời hứa hoặc tương tự. Dù sao, bạn đã bỏ lỡ một cuộc gọi lại khác

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

một nơi khác

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

điều này dường như không hoạt động vì callbackData () không được định nghĩa là một hàm?
Hugo Koopmans,

1

Tôi nghĩ đã quá muộn để trả lời câu hỏi này nhưng tôi gặp phải vấn đề tương tự gần đây, trường hợp sử dụng của tôi là gọi API JSON được phân trang và lấy tất cả dữ liệu từ mỗi phân trang và nối nó vào một mảng.

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

Giống như @ackuser đã đề cập, chúng tôi có thể sử dụng mô-đun khác nhưng Trong trường hợp sử dụng của tôi, tôi phải sử dụng nút https. Hy vọng điều này sẽ giúp ích cho những người khác.


1
Cảm ơn anh bạn, tôi đã gặp phải trường hợp giống như bạn, thật tệ là chúng ta chỉ có thể sử dụng httpsyêu cầu https để phát hành.
kenshinji
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.