Come posso effettuare una richiesta HTTP da Node.js o Express.js? Devo connettermi a un altro servizio. Spero che la chiamata sia asincrona e che il callback contenga la risposta del server remoto.
Come posso effettuare una richiesta HTTP da Node.js o Express.js? Devo connettermi a un altro servizio. Spero che la chiamata sia asincrona e che il callback contenga la risposta del server remoto.
Risposte:
Ecco uno snippet di codice da un mio esempio. È asincrono e restituisce un oggetto JSON. Può fare qualsiasi forma di richiesta GET.
Si noti che ci sono modi più ottimali (solo un esempio) - ad esempio, invece di concatenare i blocchi che si inseriscono in un array e si uniscono ad esso, ecc. Speriamo che inizi nella giusta direzione:
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();
};
Viene chiamato creando un oggetto opzioni come:
const options = {
host: 'somesite.com',
port: 443,
path: '/some/path',
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
};
E fornendo una funzione di richiamata.
Ad esempio, in un servizio, ho bisogno del modulo REST sopra e quindi faccio questo:
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);
});
Se stai cercando async
/ await
(lineare, nessun callback), promesse, supporto per il tempo di compilazione e intellisense, abbiamo creato un client HTTP e REST leggero che si adatta a quel conto:
Prova a utilizzare la semplice http.get(options, callback)
funzione in 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);
});
Esiste anche una http.request(options, callback)
funzione generale che consente di specificare il metodo di richiesta e altri dettagli della richiesta.
GET
richiesta se ho questo URL? graph.facebook.com/debug_token? input_token={token-to-inspect} &access_token={app-token-or-admin-token}
?
Request e Superagent sono librerie abbastanza buone da usare.
nota: la richiesta è obsoleta , utilizzare a proprio rischio!
Utilizzando 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
});
Puoi anche usare Requestify , un client HTTP davvero interessante e molto semplice che ho scritto per nodeJS + che supporta la memorizzazione nella cache.
Effettuate le seguenti operazioni per la richiesta del metodo 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();
}
);
Questa versione si basa sulla funzione inizialmente proposta dalla funzione bryanmac che utilizza promesse, migliore gestione degli errori e viene riscritta in 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();
});
};
Di conseguenza non è necessario passare una funzione di callback, ma getJSON () restituisce una promessa. Nel seguente esempio la funzione viene utilizzata all'interno di un gestore di route 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);
});
});
In caso di errore, delega l'errore al middleware di gestione degli errori del server.
get
definizione di percorso Express , che manca a molti post qui.
Unirest è la migliore libreria che abbia mai incontrato per fare richieste HTTP da Node. L'obiettivo è quello di essere un framework multipiattaforma, quindi imparare come funziona su Node ti servirà bene se devi usare un client HTTP su Ruby, PHP, Java, Python, Objective C, .Net o Windows 8. Per quanto ne so, le librerie unirest sono per lo più supportate da client HTTP esistenti (ad es. Su Java, il client HTTP Apache, su Node, richiesta libary di Mikeal ) - Unirest mette semplicemente in cima un'API più bella.
Ecco un paio di esempi di codice per 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)
}
})
Puoi passare direttamente ai documenti del nodo qui
Dai un'occhiata a brandelli . È un client HTTP nodo creato e gestito da spire.io che gestisce reindirizzamenti, sessioni e risposte JSON. È ottimo per interagire con le API di riposo. Vedi questo post del blog per maggiori dettagli.
Se hai solo bisogno di rendere semplici richieste get e non hai bisogno di supporto per altri metodi HTTP, dai un'occhiata a: 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
});
Usa reqclient : non progettato per scopi di scripting come request
o molte altre librerie. Reqclient consente nel costruttore di specificare molte configurazioni utili quando è necessario riutilizzare più volte la stessa configurazione: URL di base, intestazioni, opzioni di autenticazione, opzioni di registrazione, memorizzazione nella cache, ecc. Dispone inoltre di utili funzioni come analisi di query e URL, codifica automatica delle query e Analisi JSON, ecc.
Il modo migliore per utilizzare la libreria è creare un modulo per esportare l'oggetto che punta all'API e le configurazioni necessarie per connettersi con:
Modulo 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
E nei controller in cui è necessario consumare l'API utilizzare in questo modo:
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
supporta molte funzionalità, ma ne ha alcune che non sono supportate da altre librerie: integrazione OAuth2 e integrazione logger con sintassi cURL e restituisce sempre oggetti Promise nativi.
Se hai bisogno di inviare GET
richiesta a un IP
così come un Domain
(Altre risposte non ha menzionato è possibile specificare una port
variabile), è possibile fare uso di questa funzione:
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);
});
}
Non perdere i moduli richiesti nella parte superiore del tuo file:
http = require("http");
url = require('url')
Ricorda inoltre che puoi utilizzare il https
modulo per comunicare su una rete protetta. quindi queste due righe cambieranno:
https = require("https");
...
https.get(url.format(requestUrl), (resp) => { ......
## 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)=>{
})