HTTP GET Запит у Node.js Express


192

Як я можу зробити запит HTTP з Node.js або Express.js? Мені потрібно підключитися до іншої служби. Я сподіваюся, що виклик є асинхронним і що зворотний дзвінок містить відповідь віддаленого сервера.

Відповіді:


220

Ось фрагмент якогось коду з мого зразка. Це асинхронно і повертає об'єкт JSON. Він може виконувати будь-яку форму GET-запиту.

Зауважте, що існують більш оптимальні способи (лише зразок) - наприклад, замість того, щоб об'єднувати шматки, які ви кладете в масив і приєднуєтесь до нього тощо.

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

Це викликається створенням об'єкта параметрів, таких як:

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

І надання функції зворотного дзвінка.

Наприклад, в сервісі мені потрібен модуль REST вище, а потім виконайте це:

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

ОНОВЛЕННЯ

Якщо ви шукаєте async/ await(лінійний, без зворотного виклику), обіцянки, компілюємо підтримку часу та intellisense, ми створили легкий клієнт HTTP та REST, який відповідає цьому рахунку:

Microsoft набрала-відпочинок-клієнт


@bryanmac чи можете ви надіслати / додати повний зразок?
StErMi

@bryanmac з вашого дозволу, я хотів би використовувати цей кодекс grunt плагін, який я зараз будую. Не впевнений, коли, але це буде зроблено відкритим джерелом після завершення.
JeffH

3
спробуйте модуль запиту .. це набагато простіше sitepoint.com/making-http-requests-in-node-js
saurshaz

6
так - модуль запиту простий, але на нижньому рівні показано, що робить такі бібліотеки, як модуль запиту. Якщо вам потрібні запити контролю нижчого рівня або http (показує прогрес у великих завантаженнях тощо ...), це показує, як це робиться.
bryanmac

1
@KrIsHnA - у вузла є об’єкт запиту рядків : nodejs.org/api/querystring.html та об’єкт url nodejs.org/docs/latest/api/url.html
bryanmac

100

Спробуйте використовувати просту http.get(options, callback)функцію в 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);
});

Існує також загальна http.request(options, callback)функція, яка дозволяє вказувати метод запиту та інші деталі запиту.


Де вміст відповіді сервера, яку вимагала ОП?
Дан Даскалеску

Дякуємо за оновлення. Схоже, є необхідність в кінцевому оброблювачі, щоб потім об'єднати шматки. Що в основному означає відповідь @ bryanmac?
Дан Даскалеску

@DanDascalescu: так, якщо ви хочете обробляти тіло в цілому (що, швидше за все,), ви, ймовірно, хочете його передати в буфер і обробити на "кінець". Я також оновлю свою відповідь для повноти.
maerics

Вибачте, я не можу зрозуміти, з якими параметрами викликається зворотний виклик ... як я можу отримати тіло і де посилання на параметри та властивості цих параметрів.
Мухаммед Умер

@maerics Як я можу використовувати цей GETзапит, якщо у мене є ця URL-адреса? graph.facebook.com/debug_token? input_token={token-to-inspect} &access_token={app-token-or-admin-token}?
frank17

70

Запит та Superagent - досить хороші бібліотеки для використання.

Примітка: запит застарілий , використовуйте зі своїм ризиком!

Використання 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
Чи має бути res.statusCode === 200 у секунду, якщо? )
Гліб Долзіков

1
що є змінною варіантів? просто пройти невизначений? я сумніваюся в цьому
lxknvlk

32

Ви також можете використовувати Requestify , дійсно класний і дуже простий клієнт HTTP, який я написав для nodeJS + він підтримує кешування.

Просто виконайте наступне для запиту методу 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
"Спробуйте цей інший інструмент" не є прийнятною відповіддю, якщо наявний набір інструментів достатній.
Grunion Shaftoe

9

Ця версія заснована на спочатку запропонованій bryanmac функцією, яка використовує обіцянки, кращу обробку помилок і переписана в 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();
    });
};

В результаті вам не потрібно переходити у функцію зворотного дзвінка, натомість getJSON () повертає обіцянку. У наступному прикладі функція використовується всередині обробника маршрутів 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);
    });
});

При помилці він делегує помилку серверу, що обробляє помилку.


1
Так, цей приклад показує, як це зробити всередині getвизначення маршруту Express , якого не вистачає багатьом публікаціям тут.
Мікрос

7

Unirest - найкраща бібліотека, з якою я стикався для створення HTTP-запитів від Node. Він спрямований на те, щоб бути мультиплатформою, тому навчитися, як це працює на Node, буде добре, якщо вам потрібно використовувати клієнт HTTP на Ruby, PHP, Java, Python, Objective C, .Net або Windows 8. Наскільки я можу сказати, найбільш універсальні бібліотеки підтримуються в основному існуючими HTTP-клієнтами (наприклад, на Java, клієнті Apache HTTP, на Node, Mibrea's Request libary ) - Unirest просто ставить приємніший API поверх.

Ось кілька прикладів коду для 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)
    }
  })

Ви можете перейти прямо до вузла документи тут


3

Перевірте клаптик . Це клієнтський HTTP-клієнт, створений і підтримується spire.io, який обробляє переадресації, сеанси та відповіді JSON. Він відмінно підходить для взаємодії з API відпочинку. Дивіться цю публікацію в блозі для отримання детальної інформації


3

Перевірте httpreq : це бібліотека вузлів, яку я створив, тому що я був розчарований, там не було простого модуля http GET або POST ;-)


0

Якщо вам просто потрібно зробити прості запити на отримання, і вам не потрібна підтримка будь-яких інших методів HTTP, подивіться на: 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

Використовуйте reqclient : не призначений для сценаріїв, як, наприклад, requestчи багатьох інших бібліотек. Reqclient дозволяє в конструкторі вказати безліч конфігурацій, корисних, коли вам потрібно знову і знову використовувати одну і ту ж конфігурацію: базова URL-адреса, заголовки, параметри аутентифікації, параметри журналу, кешування тощо. JSON розбір тощо.

Найкращим способом використання бібліотеки є створення модуля для експорту об'єкта, що вказує на API, та необхідних конфігурацій для з'єднання:

Модуль 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

А в контролерах, де потрібно споживати API, використовується так:

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

reqclientпідтримує безліч функцій, але в ньому є деякі, які не підтримуються іншими бібліотеками: інтеграція OAuth2 та інтеграція реєстратора з синтаксисом cURL і завжди повертає рідні об'єкти Promise.


0

Якщо вам коли-небудь потрібно буде надіслати GETзапит на IPа, а також Domain(Інші відповіді не згадували, ви можете вказати portзмінну), ви можете скористатися цією функцією:

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

Не пропустіть необхідність використання модулів у верхній частині файлу:

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

Також майте на увазі, що ви можете використовувати httpsмодуль для спілкування через захищену мережу. щоб ці два рядки змінилися:

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

(Як це трапляється, це не вирішить проблему. Цей код буде слухати запит, але питання полягає в тому, як надіслати запит )
Квентін

1
це виправлено, ви можете спробувати. @Quentin
izhar ahmad
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.