Permintaan GET HTTP di Node.js Express

192

Bagaimana saya bisa membuat permintaan HTTP dari dalam Node.js atau Express.js? Saya perlu terhubung ke layanan lain. Saya berharap panggilan tidak sinkron dan bahwa panggilan balik berisi respons server jauh.

Taman Travis
sumber

Jawaban:

220

Berikut ini cuplikan dari beberapa kode dari sampel milik saya. Asinkron dan mengembalikan objek JSON. Itu bisa melakukan segala bentuk permintaan GET.

Perhatikan bahwa ada cara yang lebih optimal (hanya sampel) - misalnya, daripada menyatukan potongan yang Anda masukkan ke dalam array dan bergabung dengannya dll ... Semoga, ini membuat Anda memulai ke arah yang benar:

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

Disebut dengan membuat objek opsi seperti:

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

Dan menyediakan fungsi callback.

Misalnya, dalam sebuah layanan, saya memerlukan modul REST di atas dan kemudian lakukan ini:

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

MEMPERBARUI

Jika Anda mencari async/ await(linear, tanpa panggilan balik), janji, waktu kompilasi, dan intellisense, kami menciptakan klien HTTP dan REST yang ringan yang sesuai dengan tagihan itu:

Microsoft mengetik-rest-client

bryanmac
sumber
@bryanmac dapatkah Anda mengirim / menambahkan sampel lengkap?
StErMi
@ bryanmac dengan izin Anda, saya ingin menggunakan plugin grunt code ini yang sedang saya buat. Tidak yakin kapan tetapi akan dibuat open source saat selesai.
JeffH
3
coba permintaan modul .. itu jauh lebih sederhana sitepoint.com/making-http-requests-in-node-js
saurshaz
6
ya - modul permintaan sederhana tetapi ini adalah level bawah yang menunjukkan apa yang dilakukan perpustakaan seperti modul permintaan. Jika Anda memerlukan kontrol level yang lebih rendah atau permintaan http (menunjukkan kemajuan pada unduhan besar dll ...), ini menunjukkan bagaimana hal itu dilakukan.
bryanmac
1
@KrIsHnA - node memiliki objek querystring: nodejs.org/api/querystring.html dan objek url nodejs.org/docs/latest/api/url.html
bryanmac
100

Coba gunakan http.get(options, callback)fungsi sederhana di 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);
});

Ada juga http.request(options, callback)fungsi umum yang memungkinkan Anda menentukan metode permintaan dan detail permintaan lainnya.

maerics
sumber
Di mana isi respons server yang diminta OP?
Dan Dascalescu
Terima kasih atas pembaruannya. Sepertinya ada kebutuhan untuk pawang 'akhir' untuk menyatukan potongan itu. Yang pada dasarnya sama dengan jawaban @ bryanmac?
Dan Dascalescu
@ DanDascalescu: ya, jika Anda ingin memproses tubuh secara keseluruhan (yang kemungkinan) maka Anda mungkin ingin buffer dan proses di 'akhir'. Saya akan memperbarui jawaban saya juga untuk kelengkapan.
maerics
maaf, saya tidak tahu parameter apa yang dipanggil dengan panggilan balik ... bagaimana saya bisa mendapatkan tubuh dan di mana referensi untuk parameter dan properti parameter itu.
Muhammad Umer
@maerics Bagaimana saya bisa menggunakan GETpermintaan ini jika saya memiliki url ini? graph.facebook.com/debug_token? input_token={token-to-inspect} &access_token={app-token-or-admin-token}?
frank17
70

Permintaan dan Superagent adalah perpustakaan yang cukup bagus untuk digunakan.

catatan: permintaan sudah usang , gunakan dengan risiko Anda!

Menggunakan 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
});
staackuser2
sumber
7
Haruskah res.statusCode === 200 dalam detik jika? )
Gleb Dolzikov
1
apa variabel opsi? hanya melewati yang tidak ditentukan? saya ragu
lxknvlk
32

Anda juga dapat menggunakan Requestify , benar-benar dingin dan sangat sederhana HTTP klien saya menulis untuk nodeJS + mendukung caching.

Lakukan saja yang berikut ini untuk permintaan metode 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();
  }
);
ranm8
sumber
1
"Coba alat lain ini" bukan respons yang dapat diterima jika set alat yang ada cukup.
Grunion Shaftoe
9

Versi ini didasarkan pada fungsi bryanmac yang awalnya diusulkan yang menggunakan janji, penanganan kesalahan yang lebih baik, dan ditulis ulang dalam 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();
    });
};

Akibatnya Anda tidak harus meneruskan fungsi panggilan balik, sebaliknya getJSON () mengembalikan janji. Dalam contoh berikut fungsi digunakan di dalam pengendali rute 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);
    });
});

Pada kesalahan ini mendelegasikan kesalahan ke server penanganan kesalahan middleware.

maqduni
sumber
1
Ya, contoh ini menunjukkan bagaimana melakukannya di dalam getdefinisi rute Ekspres , yang banyak posting di sini kurang.
Micros
7

Unirest adalah pustaka terbaik yang pernah saya temui untuk membuat permintaan HTTP dari Node. Ini bertujuan untuk menjadi kerangka kerja multi platform, jadi mempelajari cara kerjanya pada Node akan membantu Anda dengan baik jika Anda perlu menggunakan klien HTTP di Ruby, PHP, Java, Python, Objective C, .Net atau Windows 8 juga. Sejauh yang saya tahu, pustaka yang paling tidak didukung sebagian besar didukung oleh klien HTTP yang ada (misalnya di Jawa, klien HTTP Apache, pada Node, libary Permintaan Mikeal) - Unirest hanya menempatkan API yang lebih bagus di atasnya.

Berikut adalah beberapa contoh kode untuk 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)
    }
  })

Anda dapat melompat langsung ke Node docs di sini

Brian Beckett
sumber
3

Lihat rusak . Ini adalah klien HTTP node yang dibuat dan dikelola oleh spire.io yang menangani arahan ulang, sesi, dan respons JSON. Ini bagus untuk berinteraksi dengan API lainnya. Lihat posting blog ini untuk lebih jelasnya.

Jonathan McIntire
sumber
3

Lihat httpreq : ini adalah pustaka simpul yang saya buat karena saya merasa frustrasi karena tidak ada http GET atau modul POST sederhana di luar sana ;-)

Sam
sumber
0

Jika Anda hanya perlu membuat permintaan sederhana dan tidak memerlukan dukungan untuk metode HTTP lain, lihat: 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
});
benjiman
sumber
0

Gunakan reqclient : tidak dirancang untuk tujuan skrip seperti requestatau banyak perpustakaan lainnya. Reqclient memungkinkan dalam konstruktor menentukan banyak konfigurasi yang berguna ketika Anda perlu menggunakan kembali konfigurasi yang sama berulang-ulang: URL dasar, header, opsi auth, opsi logging, caching, dll. Penguraian JSON, dll.

Cara terbaik untuk menggunakan perpustakaan adalah membuat modul untuk mengekspor objek yang menunjuk ke API dan konfigurasi yang diperlukan untuk terhubung dengan:

Modul 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

Dan di pengontrol di mana Anda perlu mengkonsumsi penggunaan API seperti ini:

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

reqclientmendukung banyak fitur, tetapi memiliki beberapa yang tidak didukung oleh perpustakaan lain: OAuth2 integrasi dan integrasi logger dengan sintaks cURL , dan selalu mengembalikan objek Promise asli.

Mariano Ruiz
sumber
0

Jika Anda perlu mengirim GETpermintaan ke IPdan juga Domain(Jawaban lain tidak menyebutkan Anda dapat menentukan portvariabel), Anda dapat menggunakan fungsi ini:

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

Jangan lewatkan membutuhkan modul di bagian atas file Anda:

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

Juga perhatikan bahwa Anda dapat menggunakan httpsmodul untuk berkomunikasi melalui jaringan aman. jadi dua baris ini akan berubah:

https = require("https");
...
https.get(url.format(requestUrl), (resp) => { ......
AmiNadimi
sumber
-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)=>{
})
izhar ahmad
sumber
(Ketika itu terjadi, itu tidak akan menyelesaikan masalah. Kode ini akan mendengarkan permintaan tetapi pertanyaannya adalah menanyakan cara mengirim permintaan )
Quentin
1
sudah diperbaiki, Anda bisa mencobanya. @Quentin
izhar ahmad