¿Cómo hacer una solicitud HTTP POST en node.js?

¿Cómo puedo hacer una solicitud HTTP POST de salida, con datos, en node.js?

Aquí hay un ejemplo de cómo usar node.js para hacer una solicitud POST a la API del Comstackdor de Google:

 // 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({ 'comstacktion_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); } }); 

Actualicé el código para mostrar cómo publicar datos de un archivo, en lugar de la cadena codificada. Utiliza el comando async fs.readFile para lograr esto, publicando el código real después de una lectura exitosa. Si hay un error, se lanza, y si no hay datos, el proceso sale con un valor negativo para indicar la falla.

Esto se vuelve mucho más fácil si usa la biblioteca de solicitudes .

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

Además de proporcionar una syntax agradable, hace que las solicitudes json sean fáciles, maneja la firma oauth (para twitter, etc.), puede hacer formularios de varias partes (por ejemplo, para cargar archivos) y la transmisión.

Para instalar la solicitud use el comando npm install request

Puede usar la biblioteca de solicitudes. https://www.npmjs.com/package/request

 var request = require('request'); 

Para publicar datos JSON:

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

Para publicar datos 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); }); 

Yo uso Restler and Needle para fines de producción. Ambos son mucho más poderosos que httprequest nativo. Es posible solicitar con autenticación básica, entrada de encabezado especial o incluso cargar / descargar archivos.

En cuanto a la operación post / get, también son mucho más simples de usar que las llamadas ajax sin formato usando httprequest.

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

También puede usar Requestify , un cliente HTTP realmente genial y simple que escribí para nodeJS + y que admite el almacenamiento en caché.

Solo haz lo siguiente:

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

Para aquellos que vienen aquí en los últimos años. Ahora hay una gran variedad de bibliotecas diferentes que pueden lograr esto con una encoding mínima. Prefiero las bibliotecas livianas y elegantes para las solicitudes HTTP a menos que necesites absolutamente el control de las cosas de bajo nivel de HTTP.

Una de esas bibliotecas es Unirest

Para instalarlo, use npm .
$ npm install unirest

¡Y en Hello, World! ejemplo al que todos están acostumbrados.

 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:
Mucha gente también está sugiriendo el uso de la solicitud [2]

Vale la pena señalar que detrás de las escenas, Unirest usa la biblioteca de request .

Unirest proporciona métodos para acceder al objeto de solicitud directamente.

Ejemplo:

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

Esta es la manera más simple que uso para hacer una solicitud: usando el módulo ‘solicitud’.

Comando para instalar el módulo de ‘solicitud’:

 $ npm install request 

Código de ejemplo:

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

También puede usar el módulo ‘http’ incorporado de Node.js para realizar una solicitud.

Me gusta la simplicidad del superagente ( https://github.com/visionmedia/superagent ). La misma API en el nodo y el navegador.

Edición de 2018: últimamente, sin embargo, me he movido a usar node-fetch ( https://www.npmjs.com/package/node-fetch ), que tiene una API que coincide con fetch de los navegadores.

 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://sofes.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); }); 

Para publicar la solicitud de reposo / JSON
Simplemente podemos usar el paquete de solicitud y guardar los valores que tenemos que enviar en la variable Json.

Primero instale el paquete requerido en su consola mediante la solicitud de instalación de 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) } ); 

Encontré un video que explica cómo lograr esto: https://www.youtube.com/watch?v=nuw48-u3Yrg

Utiliza el módulo predeterminado “http” junto con los módulos “querystring” y “stringbuilder”. La aplicación toma dos números (usando dos cuadros de texto) de una página web y al enviar, devuelve la sum de esos dos (junto con la persistencia de los valores en los cuadros de texto). Este es el mejor ejemplo que pude encontrar en otro lugar.

 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('< !doctype html>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);

Esta es mi solución para POST y GET .

Acerca del método de Post :

Si el cuerpo es un objeto JSON, por lo que es importante deserializarlo con JSON.stringify y posiblemente establecer el encabezado de JSON.stringify del Content-Lenght consecuencia:

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

antes de escribirlo a la solicitud:

 request.write( bodyString ); 

Acerca de los métodos Get y Post :

El timeout puede ocurrir como una desconexión de socket , por lo que debe registrar su controlador como:

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

mientras que el controlador de request es

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

Sugiero encarecidamente registrar ambos manejadores.

El cuerpo de la respuesta está fragmentado, por lo que debe capturar fragmentos en el manejador de data :

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

Al end el body contendrá todo el cuerpo de respuesta:

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

Es seguro para envolver con una try … atrapar the JSON.parse` ya que no puede estar seguro de que se trata de un json bien formateado en realidad y no hay manera de estar seguro de ello en el momento en que realiza la solicitud.

Módulo: 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') ); }); 

Después de luchar mucho mientras creaba una utilidad de bajo nivel para manejar la publicación y obtener solicitudes para mi proyecto, decidí publicar mi esfuerzo aquí. Mucho en la línea de respuestas aceptadas, aquí hay un fragmento para hacer las solicitudes http y https POST para enviar datos 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 }); } 

Si busca solicitudes HTTP basadas en promesas, axios hace su trabajo muy bien.

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

Simple y libre de dependencia. Utiliza una promesa para que pueda esperar el resultado. Devuelve el cuerpo de respuesta y no verifica el código de estado de respuesta.

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

Publicar otro ejemplo de axios de una solicitud axios.post que utiliza opciones de configuración adicionales y encabezados personalizados.

 var postData = { email: "test@test.com", 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); }) 

Solución simple :

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