Yêu cầu HTTP GET trong Node.js Express


191

Làm cách nào tôi có thể thực hiện một yêu cầu HTTP từ bên trong Node.js hoặc Express.js? Tôi cần kết nối với một dịch vụ khác. Tôi hy vọng cuộc gọi không đồng bộ và cuộc gọi lại chứa phản hồi của máy chủ từ xa.

Câu trả lời:


219

Đây là một đoạn mã của một số mã từ một mẫu của tôi. Nó không đồng bộ và trả về một đối tượng JSON. Nó có thể thực hiện bất kỳ hình thức yêu cầu GET.

Lưu ý rằng có nhiều cách tối ưu hơn (chỉ là một mẫu) - ví dụ, thay vì ghép các đoạn bạn đặt vào một mảng và nối nó, v.v ... Hy vọng, nó sẽ giúp bạn bắt đầu đi đúng hướng:

const http = require('http');
const https = require('https');

/**
 * getJSON:  RESTful GET request returning JSON object(s)
 * @param options: http options object
 * @param callback: callback to pass the results JSON object(s) back
 */

module.exports.getJSON = (options, onResult) => {
  console.log('rest::getJSON');
  const port = options.port == 443 ? https : http;

  let output = '';

  const req = port.request(options, (res) => {
    console.log(`${options.host} : ${res.statusCode}`);
    res.setEncoding('utf8');

    res.on('data', (chunk) => {
      output += chunk;
    });

    res.on('end', () => {
      let obj = JSON.parse(output);

      onResult(res.statusCode, obj);
    });
  });

  req.on('error', (err) => {
    // res.send('error: ' + err.message);
  });

  req.end();
};

Nó được gọi bằng cách tạo một đối tượng tùy chọn như:

const options = {
  host: 'somesite.com',
  port: 443,
  path: '/some/path',
  method: 'GET',
  headers: {
    'Content-Type': 'application/json'
  }
};

Và cung cấp một chức năng gọi lại.

Ví dụ: trong một dịch vụ, tôi yêu cầu mô-đun REST ở trên và sau đó thực hiện việc này:

rest.getJSON(options, (statusCode, result) => {
  // I could work with the resulting HTML/JSON here. I could also just return it
  console.log(`onResult: (${statusCode})\n\n${JSON.stringify(result)}`);

  res.statusCode = statusCode;

  res.send(result);
});

CẬP NHẬT

Nếu bạn đang tìm kiếm async/ await(tuyến tính, không gọi lại), các lời hứa, biên dịch hỗ trợ thời gian và intellisense, chúng tôi đã tạo một ứng dụng khách HTTP và REST nhẹ phù hợp với hóa đơn đó:

Microsoft gõ-rest-client


@bryanmac bạn có thể vui lòng gửi / thêm mẫu hoàn chỉnh không?
StErMi

@bryanmac với sự cho phép của bạn Tôi muốn sử dụng plugin grunt mã này tôi hiện đang xây dựng. Không chắc chắn khi nào nhưng nó sẽ được mở nguồn khi hoàn thành.
JeffH

3
thử mô-đun theo yêu cầu .. nó đơn giản hơn nhiều sitepoint.com/making-http-requests-in-node-js
saurshaz

6
có - mô-đun yêu cầu đơn giản nhưng đây là mức thấp hơn cho thấy các thư viện như mô-đun yêu cầu đang làm gì. Nếu bạn cần kiểm soát cấp thấp hơn hoặc yêu cầu http (hiển thị tiến trình trên các lượt tải lớn, v.v ...), điều này cho thấy cách thực hiện.
bryanmac

1
@KrIsHnA - node có một đối tượng chuỗi truy vấn: nodejs.org/api/querystring.html và đối tượng url nodejs.org/docs/latest/api/url.html
bryanmac

100

Hãy thử sử dụng http.get(options, callback)hàm đơn giản trong node.js:

var http = require('http');
var options = {
  host: 'www.google.com',
  path: '/index.html'
};

var req = http.get(options, function(res) {
  console.log('STATUS: ' + res.statusCode);
  console.log('HEADERS: ' + JSON.stringify(res.headers));

  // Buffer the body entirely for processing as a whole.
  var bodyChunks = [];
  res.on('data', function(chunk) {
    // You can process streamed parts here...
    bodyChunks.push(chunk);
  }).on('end', function() {
    var body = Buffer.concat(bodyChunks);
    console.log('BODY: ' + body);
    // ...and/or process the entire body here.
  })
});

req.on('error', function(e) {
  console.log('ERROR: ' + e.message);
});

Ngoài ra còn có một http.request(options, callback)chức năng chung cho phép bạn chỉ định phương thức yêu cầu và các chi tiết yêu cầu khác.


Nội dung phản hồi của máy chủ mà OP yêu cầu ở đâu?
Dan Dascalescu

Cảm ơn các cập nhật. Có vẻ như cần có một trình xử lý 'kết thúc' để ghép các khối sau đó. Về cơ bản số tiền trả lời của @ bryanmac là bao nhiêu?
Dan Dascalescu

@DanDascalescu: ya, nếu bạn muốn xử lý toàn bộ cơ thể (có khả năng) thì có lẽ bạn muốn đệm nó và xử lý vào 'kết thúc'. Tôi cũng sẽ cập nhật câu trả lời của mình cho đầy đủ.
maerics

xin lỗi, tôi không thể tìm ra cuộc gọi lại tham số nào được gọi với ... làm thế nào tôi có thể nhận được phần thân và đâu là tham chiếu cho các tham số và thuộc tính của tham số đó.
Muhammad Umer

@maerics Làm cách nào tôi có thể sử dụng GETyêu cầu này nếu tôi có url này? graph.facebook.com/debug_token? input_token={token-to-inspect} &access_token={app-token-or-admin-token}?
thẳng thắn 17

70

RequestSuperagent là những thư viện khá tốt để sử dụng.

lưu ý: yêu cầu không được chấp nhận , sử dụng có nguy cơ!

Sử dụng request:

var request=require('request');

request.get('https://someplace',options,function(err,res,body){
  if(err) //TODO: handle err
  if(res.statusCode === 200 ) //etc
  //TODO Do something with response
});

7
Nếu nó là res.statusCode === 200 trong giây nếu? )
Gleb Dolzikov

1
các tùy chọn biến là gì? chỉ cần vượt qua không xác định một? tôi nghi ngờ điều đó
lxknvlk

32

Bạn cũng có thể sử dụng Requestify , một ứng dụng HTTP thực sự đơn giản và rất đơn giản mà tôi đã viết cho nodeJS + nó hỗ trợ bộ đệm.

Chỉ cần làm như sau đối với yêu cầu phương thức GET:

var requestify = require('requestify');

requestify.get('http://example.com/api/resource')
  .then(function(response) {
      // Get the response body (JSON parsed or jQuery object for XMLs)
      response.getBody();
  }
);

1
"Hãy thử công cụ khác này" không phải là một phản hồi chấp nhận được nếu bộ công cụ hiện có là đủ.
Grunion Shaftoe

9

Phiên bản này được dựa trên bằng cách đề xuất ban đầu bryanmac chức năng trong đó sử dụng những lời hứa, xử lý lỗi tốt hơn, và được viết lại trong ES6.

let http = require("http"),
    https = require("https");

/**
 * getJSON:  REST get request returning JSON object(s)
 * @param options: http options object
 */
exports.getJSON = function(options)
{
    console.log('rest::getJSON');
    let reqHandler = +options.port === 443 ? https : http;

    return new Promise((resolve, reject) => {
        let req = reqHandler.request(options, (res) =>
        {
            let output = '';
            console.log('rest::', options.host + ':' + res.statusCode);
            res.setEncoding('utf8');

            res.on('data', function (chunk) {
                output += chunk;
            });

            res.on('end', () => {
                try {
                    let obj = JSON.parse(output);
                    // console.log('rest::', obj);
                    resolve({
                        statusCode: res.statusCode,
                        data: obj
                    });
                }
                catch(err) {
                    console.error('rest::end', err);
                    reject(err);
                }
            });
        });

        req.on('error', (err) => {
            console.error('rest::request', err);
            reject(err);
        });

        req.end();
    });
};

Kết quả là bạn không phải vượt qua trong hàm gọi lại, thay vào đó getJSON () trả lại một lời hứa. Trong ví dụ sau, hàm được sử dụng bên trong trình xử lý tuyến ExpressJS

router.get('/:id', (req, res, next) => {
    rest.getJSON({
        host: host,
        path: `/posts/${req.params.id}`,
        method: 'GET'
    }).then(({status, data}) => {
        res.json(data);
    }, (error) => {
        next(error);
    });
});

Khi có lỗi, nó ủy nhiệm lỗi cho máy chủ xử lý lỗi phần mềm trung gian.


1
Có, ví dụ này cho thấy cách thực hiện bên trong getđịnh nghĩa tuyến Express , điều mà nhiều bài viết ở đây còn thiếu.
Kính hiển vi

7

Unirest là thư viện tốt nhất mà tôi đã gặp để thực hiện các yêu cầu HTTP từ Node. Mục tiêu của nó là trở thành một khung công tác đa nền tảng, vì vậy, học cách nó hoạt động trên Node sẽ phục vụ tốt cho bạn nếu bạn cần sử dụng máy khách HTTP trên Ruby, PHP, Java, Python, Objective C, .Net hoặc Windows 8. Theo như tôi có thể nói rằng các thư viện đơn nhất hầu hết được hỗ trợ bởi các máy khách HTTP hiện có (ví dụ: trên Java, máy khách HTTP Apache, trên Node, libeal Request của Mikeal ) - Unirest chỉ đặt API đẹp hơn lên hàng đầu.

Dưới đây là một vài ví dụ mã cho Node.js:

var unirest = require('unirest')

// GET a resource
unirest.get('http://httpbin.org/get')
  .query({'foo': 'bar'})
  .query({'stack': 'overflow'})
  .end(function(res) {
    if (res.error) {
      console.log('GET error', res.error)
    } else {
      console.log('GET response', res.body)
    }
  })

// POST a form with an attached file
unirest.post('http://httpbin.org/post')
  .field('foo', 'bar')
  .field('stack', 'overflow')
  .attach('myfile', 'examples.js')
  .end(function(res) {
    if (res.error) {
      console.log('POST error', res.error)
    } else {
      console.log('POST response', res.body)
    }
  })

Bạn có thể nhảy thẳng đến tài liệu Node tại đây



3

Hãy xem httpreq : đó là thư viện nút do tôi tạo vì tôi cảm thấy thất vọng vì không có mô-đun http GET hoặc POST đơn giản nào ngoài đó ;-)


0

Nếu bạn chỉ cần thực hiện các yêu cầu nhận đơn giản và không cần hỗ trợ cho bất kỳ phương thức HTTP nào khác, hãy xem: Simple-get :

var get = require('simple-get');

get('http://example.com', function (err, res) {
  if (err) throw err;
  console.log(res.statusCode); // 200
  res.pipe(process.stdout); // `res` is a stream
});

0

Sử dụng reqclient : không được thiết kế cho mục đích kịch bản như requesthoặc nhiều thư viện khác. Reqclient cho phép trong hàm tạo xác định nhiều cấu hình hữu ích khi bạn cần sử dụng lại cùng một cấu hình: URL cơ sở, tiêu đề, tùy chọn xác thực, tùy chọn ghi nhật ký, bộ đệm, v.v. Phân tích cú pháp JSON, v.v.

Cách tốt nhất để sử dụng thư viện là tạo một mô-đun để xuất đối tượng trỏ đến API và các cấu hình cần thiết để kết nối với:

Mô-đun client.js:

let RequestClient = require("reqclient").RequestClient

let client = new RequestClient({
  baseUrl: "https://myapp.com/api/v1",
  cache: true,
  auth: {user: "admin", pass: "secret"}
})

module.exports = client

Và trong các bộ điều khiển nơi bạn cần sử dụng API như thế này:

let client = require('client')
//let router = ...

router.get('/dashboard', (req, res) => {
  // Simple GET with Promise handling to https://myapp.com/api/v1/reports/clients
  client.get("reports/clients")
    .then(response => {
       console.log("Report for client", response.userId)  // REST responses are parsed as JSON objects
       res.render('clients/dashboard', {title: 'Customer Report', report: response})
    })
    .catch(err => {
      console.error("Ups!", err)
      res.status(400).render('error', {error: err})
    })
})

router.get('/orders', (req, res, next) => {
  // GET with query (https://myapp.com/api/v1/orders?state=open&limit=10)
  client.get({"uri": "orders", "query": {"state": "open", "limit": 10}})
    .then(orders => {
      res.render('clients/orders', {title: 'Customer Orders', orders: orders})
    })
    .catch(err => someErrorHandler(req, res, next))
})

router.delete('/orders', (req, res, next) => {
  // DELETE with params (https://myapp.com/api/v1/orders/1234/A987)
  client.delete({
    "uri": "orders/{client}/{id}",
    "params": {"client": "A987", "id": 1234}
  })
  .then(resp => res.status(204))
  .catch(err => someErrorHandler(req, res, next))
})

reqclienthỗ trợ nhiều tính năng, nhưng nó có một số tính năng không được các thư viện khác hỗ trợ: tích hợp OAuth2 và tích hợp logger với cú pháp cURL và luôn trả về các đối tượng Promise gốc.


0

Nếu bạn cần gửi GETyêu cầu đến IPmột Domain(Các câu trả lời khác không đề cập đến bạn có thể chỉ định một portbiến), bạn có thể sử dụng chức năng này:

function getCode(host, port, path, queryString) {
    console.log("(" + host + ":" + port + path + ")" + "Running httpHelper.getCode()")

    // Construct url and query string
    const requestUrl = url.parse(url.format({
        protocol: 'http',
        hostname: host,
        pathname: path,
        port: port,
        query: queryString
    }));

    console.log("(" + host + path + ")" + "Sending GET request")
    // Send request
    console.log(url.format(requestUrl))
    http.get(url.format(requestUrl), (resp) => {
        let data = '';

        // A chunk of data has been received.
        resp.on('data', (chunk) => {
            console.log("GET chunk: " + chunk);
            data += chunk;
        });

        // The whole response has been received. Print out the result.
        resp.on('end', () => {
            console.log("GET end of response: " + data);
        });

    }).on("error", (err) => {
        console.log("GET Error: " + err);
    });
}

Đừng bỏ lỡ các mô-đun yêu cầu ở đầu tệp của bạn:

http = require("http");
url = require('url')

Cũng lưu ý rằng bạn có thể sử dụng httpsmô-đun để liên lạc qua mạng được bảo mật. vì vậy hai dòng này sẽ thay đổi:

https = require("https");
...
https.get(url.format(requestUrl), (resp) => { ......

-1
## you can use request module and promise in express to make any request ##
const promise                       = require('promise');
const requestModule                 = require('request');

const curlRequest =(requestOption) =>{
    return new Promise((resolve, reject)=> {
        requestModule(requestOption, (error, response, body) => {
            try {
                if (error) {
                    throw error;
                }
                if (body) {

                    try {
                        body = (body) ? JSON.parse(body) : body;
                        resolve(body);
                    }catch(error){
                        resolve(body);
                    }

                } else {

                    throw new Error('something wrong');
                }
            } catch (error) {

                reject(error);
            }
        })
    })
};

const option = {
    url : uri,
    method : "GET",
    headers : {

    }
};


curlRequest(option).then((data)=>{
}).catch((err)=>{
})

(Khi nó xảy ra, nó sẽ không giải quyết được vấn đề. Mã này sẽ lắng nghe yêu cầu nhưng câu hỏi là hỏi làm thế nào để gửi yêu cầu )
Quentin

1
nó đã được sửa, bạn có thể dùng thử @Quentin
izhar ahmad
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.