Come fare una richiesta POST HTTP in node.js?

Come posso creare una richiesta POST HTTP in uscita, con dati, in node.js?

Ecco un esempio dell’utilizzo di node.js per effettuare una richiesta POST all’API di Google Compiler:

 // We need this to build our post string var querystring = require('querystring'); var http = require('http'); var fs = require('fs'); function PostCode(codestring) { // Build the post string from an object var post_data = querystring.stringify({ 'compilation_level' : 'ADVANCED_OPTIMIZATIONS', 'output_format': 'json', 'output_info': 'compiled_code', 'warning_level' : 'QUIET', 'js_code' : codestring }); // An object of options to indicate where to post to var post_options = { host: 'closure-compiler.appspot.com', port: '80', path: '/compile', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(post_data) } }; // Set up the request var post_req = http.request(post_options, function(res) { res.setEncoding('utf8'); res.on('data', function (chunk) { console.log('Response: ' + chunk); }); }); // post the data post_req.write(post_data); post_req.end(); } // This is an async file read fs.readFile('LinkedList.js', 'utf-8', function (err, data) { if (err) { // If this were just a small part of the application, you would // want to handle this differently, maybe throwing an exception // for the caller to handle. Since the file is absolutely essential // to the program's functionality, we're going to exit with a fatal // error instead. console.log("FATAL An error occurred trying to read in the file: " + err); process.exit(-2); } // Make sure there's data before we post it if(data) { PostCode(data); } else { console.log("No data to post"); process.exit(-1); } }); 

Ho aggiornato il codice per mostrare come pubblicare i dati da un file, invece della stringa hardcoded. Utilizza il comando fs.readFile async per ottenere ciò, pubblicando il codice effettivo dopo una lettura corretta. Se c’è un errore, viene lanciato e se non ci sono dati il ​​processo esce con un valore negativo per indicare un errore.

Questo diventa molto più semplice se si utilizza la libreria richiesta .

 var request = require('request'); request.post( 'http://www.yoursite.com/formpage', { json: { key: 'value' } }, function (error, response, body) { if (!error && response.statusCode == 200) { console.log(body) } } ); 

Oltre a fornire una buona syntax, semplifica le richieste JSON, gestisce la firma oauth (per Twitter, ecc.), Può creare moduli multiparte (ad esempio per caricare file) e lo streaming.

Per installare la richiesta usa comando npm install request

Puoi usare la libreria delle richieste. https://www.npmjs.com/package/request

 var request = require('request'); 

Per pubblicare i dati JSON:

 var myJSONObject = { ... }; request({ url: "http://josiahchoi.com/myjson", method: "POST", json: true, // <--Very important!!! body: myJSONObject }, function (error, response, body){ console.log(response); }); 

Per pubblicare dati xml:

 var myXMLText = '...........' request({ url: "http://josiahchoi.com/myjson", method: "POST", headers: { "content-type": "application/xml", // <--Very important!!! }, body: myXMLText }, function (error, response, body){ console.log(response); }); 

Uso Restler e Needle per scopi di produzione. Sono entrambi molto più potenti di httprequest nativo. È ansible richiedere l’autenticazione di base, l’immissione di intestazione speciale o persino caricare / scaricare file.

Per quanto riguarda le operazioni di post-acquisizione, sono anche molto più semplici da usare rispetto alle chiamate ajax non formattate usando httprequest.

 needle.post('https://my.app.com/endpoint', {foo:'bar'}, function(err, resp, body){ console.log(body); }); 

È inoltre ansible utilizzare Requestify , un client HTTP veramente bello e semplice che ho scritto per nodeJS + che supporta il caching.

Basta fare quanto segue:

  var requestify = require('requestify'); requestify.post('http://example.com', { hello: 'world' }) .then(function(response) { // Get the response body (JSON parsed or jQuery object for XMLs) response.getBody(); }); 

Per quelli che vengono qui negli ultimi anni. Esistono ora una vasta gamma di librerie diverse che possono ottenere questo risultato con una codifica minima. Preferisco di gran lunga le librerie leggere leggere per le richieste HTTP, a meno che non sia assolutamente necessario controllare il materiale HTTP di basso livello.

Una di queste librerie è Unirest

Per installarlo, usa npm .
$ npm install unirest

E su Hello, World! esempio a cui tutti sono abituati.

 var unirest = require('unirest'); unirest.post('http://example.com/helloworld') .header('Accept', 'application/json') .send({ "Hello": "World!" }) .end(function (response) { console.log(response.body); }); 

Extra:
Molte persone suggeriscono anche l’uso della richiesta [2]

Vale la pena notare che dietro le quinte Unirest usa la libreria delle request .

Unirest fornisce metodi per accedere direttamente all’object richiesta.

Esempio:

 var Request = unirest.get('http://mockbin.com/request'); 

Questo è il modo più semplice che uso per fare una richiesta: usando il modulo ‘richiesta’.

Comando per installare il modulo ‘richiesta’:

 $ npm install request 

Codice di esempio:

 var request = require('request') var options = { method: 'post', body: postData, // Javascript object json: true, // Use,If you are sending JSON data url: url, headers: { // Specify headers, If any } } request(options, function (err, res, body) { if (err) { console.log('Error :', err) return } console.log(' Body :', body) }); 

Puoi anche utilizzare il modulo ‘http’ integrato di Node.js per effettuare una richiesta.

Mi piace la semplicità di superagent ( https://github.com/visionmedia/superagent ). Stessa API su entrambi i nodes e browser.

Modifica 2018: ultimamente, però, mi sono spostato sull’uso di node-fetch ( https://www.npmjs.com/package/node-fetch ), che ha un’API che corrisponde al fetch dai browser.

 var https = require('https'); /** * HOW TO Make an HTTP Call - POST */ // do a POST request // create the JSON object jsonObject = JSON.stringify({ "message" : "The web of things is approaching, let do some tests to be ready!", "name" : "Test message posted with node.js", "caption" : "Some tests with node.js", "link" : "http://www.youscada.com", "description" : "this is a description", "picture" : "http://sofit.miximages.com/node.js/logo2.png", "actions" : [ { "name" : "youSCADA", "link" : "http://www.youscada.com" } ] }); // prepare the header var postheaders = { 'Content-Type' : 'application/json', 'Content-Length' : Buffer.byteLength(jsonObject, 'utf8') }; // the post options var optionspost = { host : 'graph.facebook.com', port : 443, path : '/youscada/feed?access_token=your_api_key', method : 'POST', headers : postheaders }; console.info('Options prepared:'); console.info(optionspost); console.info('Do the POST call'); // do the POST call var reqPost = https.request(optionspost, function(res) { console.log("statusCode: ", res.statusCode); // uncomment it for header details // console.log("headers: ", res.headers); res.on('data', function(d) { console.info('POST result:\n'); process.stdout.write(d); console.info('\n\nPOST completed'); }); }); // write the json data reqPost.write(jsonObject); reqPost.end(); reqPost.on('error', function(e) { console.error(e); }); 

Per postare il resto / richiesta JSON
Possiamo semplicemente usare il pacchetto di richiesta e salvare i valori che dobbiamo inviare nella variabile Json.

Per prima cosa installa il pacchetto require nella tua console tramite la richiesta di installazione di npm –save

 var request = require('request'); var options={ 'key':'28', 'key1':'value', 'key2':'value' } request({ url:"http://dev.api.ean.com/ean-services/rs/hotel/v3/ping? minorRev="+options.key+ "&cid="+options.key1+ "&apiKey="+options.key2, method:"POST", json:true},function(error,response,body){ console.log(body) } ); 

Ho trovato un video che spiega come ottenere questo risultato: https://www.youtube.com/watch?v=nuw48-u3Yrg

Usa il modulo “http” predefinito insieme ai moduli “querystring” e “stringbuilder”. L’applicazione prende due numeri (utilizzando due caselle di testo) da una pagina Web e, al momento dell’invio, restituisce la sum di questi due (insieme con la persistenza dei valori nelle caselle di testo). Questo è l’esempio migliore che ho trovato altrove.

 var http = require("http"); var qs = require("querystring"); var StringBuilder = require("stringbuilder"); var port = 9000; function getCalcHtml(req, resp, data) { var sb = new StringBuilder({ newline: "\r\n" }); sb.appendLine(""); sb.appendLine(" "); sb.appendLine(" 
"); sb.appendLine(" "); sb.appendLine(" "); sb.appendLine(" "); if (data && data.txtFirstNo) { sb.appendLine(" ", data.txtFirstNo); } else { sb.appendLine(" "); } sb.appendLine(" "); sb.appendLine(" "); sb.appendLine(" "); if (data && data.txtSecondNo) { sb.appendLine(" ", data.txtSecondNo); } else { sb.appendLine(" "); } sb.appendLine(" "); sb.appendLine(" "); sb.appendLine(" "); sb.appendLine(" "); if (data && data.txtFirstNo && data.txtSecondNo) { var sum = parseInt(data.txtFirstNo) + parseInt(data.txtSecondNo); sb.appendLine(" "); sb.appendLine(" ", sum); sb.appendLine(" "); } sb.appendLine("
Enter First No:
Enter Second No:
Sum: {0}
"); sb.appendLine("
") sb.appendLine(" "); sb.appendLine(""); sb.build(function (err, result) { resp.write(result); resp.end(); }); } function getCalcForm(req, resp, data) { resp.writeHead(200, { "Content-Type": "text/html" }); getCalcHtml(req, resp, data); } function getHome(req, resp) { resp.writeHead(200, { "Content-Type": "text/html" }); resp.write("HomeWant to some calculation? Click here"); resp.end(); } function get404(req, resp) { resp.writeHead(404, "Resource Not Found", { "Content-Type": "text/html" }); resp.write("404404: Resource not found. Go to Home"); resp.end(); } function get405(req, resp) { resp.writeHead(405, "Method not supported", { "Content-Type": "text/html" }); resp.write("405405: Method not supported"); resp.end(); } http.createServer(function (req, resp) { switch (req.method) { case "GET": if (req.url === "/") { getHome(req, resp); } else if (req.url === "https://stackoverflow.com/calc") { getCalcForm(req, resp); } else { get404(req, resp); } break; case "POST": if (req.url === "https://stackoverflow.com/calc") { var reqBody = ''; req.on('data', function (data) { reqBody += data; if (reqBody.length > 1e7) { //10MB resp.writeHead(413, 'Request Entity Too Large', { 'Content-Type': 'text/html' }); resp.end('413413: Request Entity Too Large'); } }); req.on('end', function () { var formData = qs.parse(reqBody); getCalcForm(req, resp, formData); }); } else { get404(req, resp); } break; default: get405(req, resp); break; } }).listen(port);

Questa è la mia soluzione per POST e GET .

Informazioni sul metodo Post :

Se il corpo è un object JSON, quindi è importante deserializzare con JSON.stringify ed eventualmente impostare l’intestazione Content-Lenght conseguenza:

  var bodyString=JSON.stringify(body) var _headers = { 'Content-Length': Buffer.byteLength(bodyString) }; 

prima di scriverlo alla richiesta:

 request.write( bodyString ); 

Informazioni sui metodi Get e Post :

Il timeout può verificarsi come disconnessione del socket , quindi è necessario registrare il gestore come:

 request.on('socket', function (socket) { socket.setTimeout( self.timeout ); socket.on('timeout', function() { request.abort(); if(timeout) return timeout( new Error('request timed out') ); }); }); 

mentre il gestore della request è

  request.on('timeout', function () { // Timeout happend. Server received request, but not handled it // (ie doesn't send any response or it took to long). // You don't know what happend. // It will emit 'error' message as well (with ECONNRESET code). req.abort(); if(timeout) return timeout( new Error('request timed out') ); }); 

Consiglio vivamente di registrare entrambi i gestori.

Il corpo della risposta è suddiviso in blocchi, quindi è necessario concatenare blocchi al gestore data :

  var body = ''; response.on('data', function(d) { body += d; }); 

Alla end il body conterrà l’intero corpo della risposta:

  response.on('end', function() { try { var jsonResponse=JSON.parse(body); if(success) return success( jsonResponse ); } catch(ex) { // bad json if(error) return error(ex.toString()); } }); 

È sicuro avvolgere con un try … catturare the JSON.parse` poiché non si può essere sicuri che si tratti di un json ben formattato e non c’è modo di esserne sicuri al momento della richiesta.

Modulo: SimpleAPI

 /** * Simple POST and GET * @author Loreto Parisi (loretoparisi at gmail dot com) */ (function() { var SimpleAPI; SimpleAPI = (function() { var qs = require('querystring'); /** * API Object model * @author Loreto Parisi (loretoparisi at gmail dot com) */ function SimpleAPI(host,port,timeout,ssl,debug,json) { this.host=host; this.port=port; this.timeout=timeout; /** true to use ssl - defaults to true */ this.ssl=ssl || true; /** true to console log */ this.debug=debug; /** true to parse response as json - defaults to true */ this.json= (typeof(json)!='undefined')?json:true; this.requestUrl=''; if(ssl) { // use ssl this.http = require('https'); } else { // go unsafe, debug only please this.http = require('http'); } } /** * HTTP GET * @author Loreto Parisi (loretoparisi at gmail dot com) */ SimpleAPI.prototype.Get = function(path, headers, params, success, error, timeout) { var self=this; if(params) { var queryString=qs.stringify(params); if( queryString ) { path+="?"+queryString; } } var options = { headers : headers, hostname: this.host, path: path, method: 'GET' }; if(this.port && this.port!='80') { // port only if ! 80 options['port']=this.port; } if(self.debug) { console.log( "SimpleAPI.Get", headers, params, options ); } var request=this.http.get(options, function(response) { if(self.debug) { // debug console.log( JSON.stringify(response.headers) ); } // Continuously update stream with data var body = ''; response.on('data', function(d) { body += d; }); response.on('end', function() { try { if(self.json) { var jsonResponse=JSON.parse(body); if(success) return success( jsonResponse ); } else { if(success) return success( body ); } } catch(ex) { // bad json if(error) return error( ex.toString() ); } }); }); request.on('socket', function (socket) { socket.setTimeout( self.timeout ); socket.on('timeout', function() { request.abort(); if(timeout) return timeout( new Error('request timed out') ); }); }); request.on('error', function (e) { // General error, ie // - ECONNRESET - server closed the socket unexpectedly // - ECONNREFUSED - server did not listen // - HPE_INVALID_VERSION // - HPE_INVALID_STATUS // - ... (other HPE_* codes) - server returned garbage console.log(e); if(error) return error(e); }); request.on('timeout', function () { // Timeout happend. Server received request, but not handled it // (ie doesn't send any response or it took to long). // You don't know what happend. // It will emit 'error' message as well (with ECONNRESET code). req.abort(); if(timeout) return timeout( new Error('request timed out') ); }); self.requestUrl = (this.ssl?'https':'http') + '://' + request._headers['host'] + request.path; if(self.debug) { console.log("SimpleAPI.Post",self.requestUrl); } request.end(); } //RequestGet /** * HTTP POST * @author Loreto Parisi (loretoparisi at gmail dot com) */ SimpleAPI.prototype.Post = function(path, headers, params, body, success, error, timeout) { var self=this; if(params) { var queryString=qs.stringify(params); if( queryString ) { path+="?"+queryString; } } var bodyString=JSON.stringify(body) var _headers = { 'Content-Length': Buffer.byteLength(bodyString) }; for (var attrname in headers) { _headers[attrname] = headers[attrname]; } var options = { headers : _headers, hostname: this.host, path: path, method: 'POST', qs : qs.stringify(params) }; if(this.port && this.port!='80') { // port only if ! 80 options['port']=this.port; } if(self.debug) { console.log( "SimpleAPI.Post\n%s\n%s", JSON.stringify(_headers,null,2), JSON.stringify(options,null,2) ); } if(self.debug) { console.log("SimpleAPI.Post body\n%s", JSON.stringify(body,null,2) ); } var request=this.http.request(options, function(response) { if(self.debug) { // debug console.log( JSON.stringify(response.headers) ); } // Continuously update stream with data var body = ''; response.on('data', function(d) { body += d; }); response.on('end', function() { try { console.log("END", body); var jsonResponse=JSON.parse(body); if(success) return success( jsonResponse ); } catch(ex) { // bad json if(error) return error(ex.toString()); } }); }); request.on('socket', function (socket) { socket.setTimeout( self.timeout ); socket.on('timeout', function() { request.abort(); if(timeout) return timeout( new Error('request timed out') ); }); }); request.on('error', function (e) { // General error, ie // - ECONNRESET - server closed the socket unexpectedly // - ECONNREFUSED - server did not listen // - HPE_INVALID_VERSION // - HPE_INVALID_STATUS // - ... (other HPE_* codes) - server returned garbage console.log(e); if(error) return error(e); }); request.on('timeout', function () { // Timeout happend. Server received request, but not handled it // (ie doesn't send any response or it took to long). // You don't know what happend. // It will emit 'error' message as well (with ECONNRESET code). req.abort(); if(timeout) return timeout( new Error('request timed out') ); }); self.requestUrl = (this.ssl?'https':'http') + '://' + request._headers['host'] + request.path; if(self.debug) { console.log("SimpleAPI.Post",self.requestUrl); } request.write( bodyString ); request.end(); } //RequestPost return SimpleAPI; })(); module.exports = SimpleAPI }).call(this); 

Uso:

 // Parameters // domain: example.com // ssl:true, port:80 // timeout: 30 secs // debug: true // json response:true var api = new SimpleAPI('posttestserver.com', 80, 1000 * 10, true, true, true); var headers = { 'Content-Type' : 'application/json', 'Accept' : 'application/json' }; var params = { "dir" : "post-test" }; var method = 'post.php'; api.Post(method, headers, params, body , function(response) { // success console.log( response ); } , function(error) { // error console.log( error.toString() ); } , function(error) { // timeout console.log( new Error('timeout error') ); }); 

Dopo aver faticato parecchio durante la creazione di un’utility di basso livello per gestire il post e ottenere richieste per il mio progetto, ho deciso di pubblicare il mio sforzo qui. Molto sulla linea della risposta accettata, ecco uno snippet per fare richieste POST http e https per l’invio di dati JSON.

 const http = require("http") const https = require("https") // Request handler function let postJSON = (options, postData, callback) => { // Serializing JSON post_data = JSON.stringify(postData) let port = options.port == 443 ? https : http // Callback function for the request let req = port.request(options, (res) => { let output = '' res.setEncoding('utf8') // Listener to receive data res.on('data', (chunk) => { output += chunk }); // Listener for intializing callback after receiving complete response res.on('end', () => { let obj = JSON.parse(output) callback(res.statusCode, obj) }); }); // Handle any errors occurred while making request req.on('error', (err) => { //res.send('error: ' + err.message) }); // Request is made here, with data as string or buffer req.write(post_data) // Ending the request req.end() }; let callPost = () => { let data = { 'name': 'Jon', 'message': 'hello, world' } let options = { host: 'domain.name', // Your domain name port: 443, // 443 for https and 80 for http path: '/path/to/resource', // Path for the request method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(data) } } postJSON(options, data, (statusCode, result) => { // Handle response // Process the received data }); } 

Se siete alla ricerca di richieste HTTP basate su promesse, Axios fa il suo lavoro in modo piacevole.

  const axios = require('axios'); axios.post('/user', { firstName: 'Fred', lastName: 'Flintstone' }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }); 

Semplice e senza dipendenza. Usa una promise per poter attendere il risultato. Restituisce il corpo della risposta e non controlla il codice di stato della risposta.

 const https = require('https'); function httpsPost({body, ...options}) { return new Promise((resolve,reject) => { const req = https.request({ method: 'POST', ...options, }, res => { const chunks = []; res.on('data', data => chunks.push(data)) res.on('end', () => { let body = Buffer.concat(chunks); switch(res.headers['content-type']) { case 'application/json': body = JSON.parse(body); break; } resolve(body) }) }) req.on('error',reject); if(body) { req.write(body); } req.end(); }) } 

Uso:

 const res = await httpsPost({ hostname: 'sentry.io', path: `/api/0/organizations/org/releases/${changesetId}/deploys/`, headers: { 'Authorization': `Bearer ${process.env.SENTRY_AUTH_TOKEN}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ environment: isLive ? 'production' : 'demo', }) }) 

Pubblicazione di un altro esempio di una richiesta axios.post che utilizza opzioni di configurazione aggiuntive e intestazioni personalizzate.

 var postData = { email: "[email protected]", password: "password" }; let axiosConfig = { headers: { 'Content-Type': 'application/json;charset=UTF-8', "Access-Control-Allow-Origin": "*", } }; axios.post('http://:/', postData, axiosConfig) .then((res) => { console.log("RESPONSE RECEIVED: ", res); }) .catch((err) => { console.log("AXIOS ERROR: ", err); }) 

Soluzione semplice:

  var data = { "host":"127.1.1.1", "port":9008 } request.post( baseUrl + '/peers/connect', { json: data, // your payload data placed here headers: { 'X-Api-Key': 'dajzmj6gfuzmbfnhamsbuxivc', // if authentication needed 'Content-Type': 'application/json' } }, function (error, response, body) { if (error) { callback(error, null) } else { callback(error, response.body) } });