instalar - ¿Cómo hacer una solicitud HTTP POST en node.js?
post node.js express (17)
Después de esforzarme mucho al crear una utilidad de bajo nivel para manejar la publicación y obtener solicitudes para mi proyecto, decidí publicar mi esfuerzo aquí. Mucho en las líneas de respuesta aceptada, aquí hay un fragmento para realizar solicitudes POST de http y https 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
});
}
¿Cómo puedo realizar una solicitud HTTP POST de salida, con datos, en node.js?
Encontré un video que explica cómo lograrlo: https://www.youtube.com/watch?v=nuw48-u3Yrg
Utiliza el módulo predeterminado "http" junto con los módulos de "cadena de consulta" y "constructor de cadenas". La aplicación toma dos números (usando dos cuadros de texto) de una página web y al enviarlos, devuelve la suma de esos dos (junto con la persistencia de los valores en los cuadros de texto). Este es el mejor ejemplo que pude encontrar en cualquier 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("<html>");
sb.appendLine(" <body>");
sb.appendLine(" <form method=''post''>");
sb.appendLine(" <table>");
sb.appendLine(" <tr>");
sb.appendLine(" <td>Enter First No: </td>");
if (data && data.txtFirstNo) {
sb.appendLine(" <td><input type=''text'' id=''txtFirstNo'' name=''txtFirstNo'' value=''{0}''/></td>", data.txtFirstNo);
}
else {
sb.appendLine(" <td><input type=''text'' id=''txtFirstNo'' name=''txtFirstNo'' /></td>");
}
sb.appendLine(" </tr>");
sb.appendLine(" <tr>");
sb.appendLine(" <td>Enter Second No: </td>");
if (data && data.txtSecondNo) {
sb.appendLine(" <td><input type=''text'' id=''txtSecondNo'' name=''txtSecondNo'' value=''{0}''/></td>", data.txtSecondNo);
}
else {
sb.appendLine(" <td><input type=''text'' id=''txtSecondNo'' name=''txtSecondNo'' /></td>");
}
sb.appendLine(" </tr>");
sb.appendLine(" <tr>");
sb.appendLine(" <td><input type=''submit'' value=''Calculate'' /></td>");
sb.appendLine(" </tr>");
if (data && data.txtFirstNo && data.txtSecondNo) {
var sum = parseInt(data.txtFirstNo) + parseInt(data.txtSecondNo);
sb.appendLine(" <tr>");
sb.appendLine(" <td>Sum: {0}</td>", sum);
sb.appendLine(" </tr>");
}
sb.appendLine(" </table>");
sb.appendLine(" </form>")
sb.appendLine(" </body>");
sb.appendLine("</html>");
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("<html><html><head><title>Home</title></head><body>Want to some calculation? Click <a href=''/calc''>here</a></body></html>");
resp.end();
}
function get404(req, resp) {
resp.writeHead(404, "Resource Not Found", { "Content-Type": "text/html" });
resp.write("<html><html><head><title>404</title></head><body>404: Resource not found. Go to <a href=''/''>Home</a></body></html>");
resp.end();
}
function get405(req, resp) {
resp.writeHead(405, "Method not supported", { "Content-Type": "text/html" });
resp.write("<html><html><head><title>405</title></head><body>405: Method not supported</body></html>");
resp.end();
}
http.createServer(function (req, resp) {
switch (req.method) {
case "GET":
if (req.url === "/") {
getHome(req, resp);
}
else if (req.url === "/calc") {
getCalcForm(req, resp);
}
else {
get404(req, resp);
}
break;
case "POST":
if (req.url === "/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><html><head><title>413</title></head><body>413: Request Entity Too Large</body></html>'');
}
});
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 la forma más sencilla que utilizo para realizar una solicitud: usando el módulo ''solicitud''.
Comando para instalar el módulo ''petición'':
$ 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 la solicitud.
Esta es mi solución para POST
y GET
.
Sobre el método de Post
:
Si el cuerpo es un objeto JSON, es importante deserializarlo con JSON.stringify
y posiblemente establecer el encabezado 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 manejador de request
es
request.on(''timeout'', function () {
// Timeout happend. Server received request, but not handled it
// (i.e. 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'') );
});
Recomiendo encarecidamente registrar ambos manejadores.
El cuerpo de la respuesta está fragmentado, por lo que debe calcular los 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 envolver con un try
... capturar the
JSON.parse` ya que no puede estar seguro de que sea un json bien formateado en realidad y no hay forma de estar seguro de ello en el momento en que realice 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, i.e.
// - 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
// (i.e. 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, i.e.
// - 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
// (i.e. 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'') );
});
Este es un ejemplo del uso de node.js para realizar una solicitud POST a la API del compilador 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({
''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);
}
});
He actualizado 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 un error.
Esto se vuelve mucho más fácil si usas la biblioteca de request .
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 buena sintaxis, facilita las solicitudes json, maneja una firma real (para twitter, etc.), puede hacer formularios de varias partes (por ejemplo, para cargar archivos) y transmisión.
Para instalar la solicitud use el comando npm install request
Me gusta la simplicidad de superagent ( https://github.com/visionmedia/superagent ). La misma api tanto en el nodo como en el navegador.
Edición 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 la fetch
desde los navegadores.
Mediante el uso de la dependencia de la https://www.npmjs.com/package/request .
Solución simple :
import request from ''request''
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)
}
});
Para los que vienen aquí en los últimos años. Ahora hay una gran variedad de bibliotecas diferentes que pueden lograr esto con una codificación mínima. Prefiero las bibliotecas elegantes y ligeras para las solicitudes HTTP, a menos que sea absolutamente necesario controlar las cosas HTTP de bajo nivel.
Una de esas bibliotecas es Unirest
Para instalarlo, utiliza npm
.
$ npm install unirest
¡Y en el Hello, World!
Ejemplo al que todos estamos 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 request https://www.npmjs.com/package/request
Merece la pena tener en cuenta que, entre bastidores, Unirest
utiliza la biblioteca de request
.
Unirest proporciona métodos para acceder al objeto de solicitud directamente.
Ejemplo:
var Request = unirest.get(''http://mockbin.com/request'');
Publicación de otro ejemplo de axios de una solicitud axios.post que usa opciones de configuración adicionales y encabezados personalizados.
var postData = {
email: "[email protected]",
password: "password"
};
let axiosConfig = {
headers: {
''Content-Type'': ''application/json;charset=UTF-8'',
"Access-Control-Allow-Origin": "*",
}
};
axios.post(''http://<host>:<port>/<path>'', postData, axiosConfig)
.then((res) => {
console.log("RESPONSE RECEIVED: ", res);
})
.catch((err) => {
console.log("AXIOS ERROR: ", err);
})
Puede utilizar 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 = ''<xml>...........</xml>''
request({
url: "http://josiahchoi.com/myjson",
method: "POST",
headers: {
"content-type": "application/xml", // <--Very important!!!
},
body: myXMLText
}, function (error, response, body){
console.log(response);
});
Sencillo y sin dependencia. Utiliza una promesa para que puedas 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'',
})
})
Si está buscando solicitudes HTTP basadas en promesa, 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);
});
También puedes usar Requestify , un cliente HTTP realmente genial y simple que escribí para nodeJS + 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();
});
Uso Restler y Needle para fines de producción. Ambos son mucho más poderosos que la petición http nativa. Es posible solicitar con autenticación básica, entrada de encabezado especial o incluso cargar / descargar archivos.
En cuanto a la operación de publicación / obtención, también son mucho más fáciles de usar que las llamadas ajax en bruto que utilizan httprequest.
needle.post(''https://my.app.com/endpoint'', {foo:''bar''},
function(err, resp, body){
console.log(body);
});
Para Publicar Resto / Solicitud 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 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)
}
);
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://youscada.com/wp-content/uploads/2012/05/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);
});