¿Cómo procesar datos POST en Node.js?

637

¿Cómo extrae los datos del formulario ( form[method="post"]) y las cargas de archivos enviados desde el POSTmétodo HTTP en Node.js ?

He leído la documentación, busqué en Google y no encontré nada.

function (request, response) {
    //request.post????
}

¿Hay una biblioteca o un truco?

Ming-Tang
fuente

Respuestas:

552

Si usa Express (desarrollo web de alto rendimiento y alta clase para Node.js), puede hacer esto:

HTML:

<form method="post" action="/">
    <input type="text" name="user[name]">
    <input type="text" name="user[email]">
    <input type="submit" value="Submit">
</form>

Cliente API:

fetch('/', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({
        user: {
            name: "John",
            email: "[email protected]"
        }
    })
});

Node.js: (desde Express v4.16.0)

// Parse URL-encoded bodies (as sent by HTML forms)
app.use(express.urlencoded());

// Parse JSON bodies (as sent by API clients)
app.use(express.json());

// Access the parse results as request.body
app.post('/', function(request, response){
    console.log(request.body.user.name);
    console.log(request.body.user.email);
});

Node.js: (para Express <4.16.0)

const bodyParser = require("body-parser");

/** bodyParser.urlencoded(options)
 * Parses the text as URL encoded data (which is how browsers tend to send form data from regular forms set to POST)
 * and exposes the resulting object (containing the keys and values) on req.body
 */
app.use(bodyParser.urlencoded({
    extended: true
}));

/**bodyParser.json(options)
 * Parses the text as JSON and exposes the resulting object on req.body.
 */
app.use(bodyParser.json());

app.post("/", function (req, res) {
    console.log(req.body.user.name)
});
Baggz
fuente
45
La funcionalidad está realmente en el módulo BodyParser en connect, si desea utilizar un punto de entrada de nivel inferior.
Julian Birch
14
Estoy confundido. ¿Cómo corresponde name = "user [email]" a request.body.email?
sbose
36
¡¡Dios!! Me estoy volviendo loco al tener que leer 3 duplicaciones al mismo tiempo para el mismo marco: / nodejs.org/api/http.html , senchalabs.org/connect & expressjs.com/guide.html
Salman von Abbas
15
Esto no funcionó para mí hasta que agregué app.use(express.bodyParser());.
Pettys
13
Express es hacer un nodo de lo que jQuery es para el lado del cliente JS. Cada vez que busco en Google la ayuda para el nodo, obtengo estos cojos "¡use express! respuestas ¿Es realmente tan difícil analizar los datos de publicación que justifica la instalación de un marco web completo?
Shawn Whinnery
710

Puedes usar el querystringmódulo:

var qs = require('querystring');

function (request, response) {
    if (request.method == 'POST') {
        var body = '';

        request.on('data', function (data) {
            body += data;

            // Too much POST data, kill the connection!
            // 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB
            if (body.length > 1e6)
                request.connection.destroy();
        });

        request.on('end', function () {
            var post = qs.parse(body);
            // use post['blah'], etc.
        });
    }
}

Ahora, por ejemplo, si tiene un inputcampo con nombre age, puede acceder a él utilizando la variable post:

console.log(post.age);
Casey Chu
fuente
8
@thejh Hm, ese es un buen punto. Sin embargo, no debería ser difícil agregar eso, así que lo dejaré fuera del ejemplo para mantener las cosas simples.
Casey Chu
72
El desarrollo del servidor web de node.js está plagado de middlewarez que requiere que los estudies durante horas para ahorrarte minutos de codificación. Y mucho menos la escasa documentación que ofrecen casi todos. Y su aplicación termina dependiendo de los criterios de otras personas, no de los suyos. Además de cualquier número de problemas de rendimiento.
Juan Lanus
44
var POST = qs.parse(body); // use POST solo para novatos como yo: cuando el nombre del campo de texto de entrada es "usuario", Post.usermostrará los datos de ese campo. por ejemploconsole.log(Post.user);
Michael Moeller
55
También podría usar la readabledevolución de llamada en lugar de construir los datos en una cadena de cuerpo. Una vez que se dispara, el cuerpo está disponible a través derequest.read();
Thomas Fankhauser
44
¡Tenga en cuenta que eso req.connection.destroy(); no impide que se ejecuten las devoluciones de llamada! Por ejemplo, la devolución de llamada "al final" se ejecutará con el cuerpo truncado. Esto probablemente no es lo que quiere ...
collimarco
149

¡Asegúrate de cerrar la conexión si alguien intenta inundar tu RAM!

var qs = require('querystring');

function (request, response) {
    if (request.method == 'POST') {
        var body = '';
        request.on('data', function (data) {
            body += data;
            // 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB
            if (body.length > 1e6) { 
                // FLOOD ATTACK OR FAULTY CLIENT, NUKE REQUEST
                request.connection.destroy();
            }
        });
        request.on('end', function () {

            var POST = qs.parse(body);
            // use POST

        });
    }
}
thejh
fuente
53
También puede devolver el código de error HTTP 413 (entidad de solicitud demasiado grande)
neoascético
1
@SSHThis: No, es 1 * 10 ^ 6 = 1000000.
thejh
@tq: en este caso, POST [nombre] (por ejemplo, POST ["foo"]).
thejh
2
var POST = qs.parse(body); // use POST solo para novatos: cuando el nombre del campo de texto de entrada es "usuario", Post.user mostrará los datos de ese campo. eg console.log (Post.user);
Michael Moeller
2
¿Puede alguien ayudarme si publico {'Nombre': 'Joe'} Me sale {{'Nombre': 'Joe'}: ''} después de qs.Parse (POST) ...
Matt Canty
118

Muchas de las respuestas aquí ya no son buenas prácticas o no explican nada, así que por eso estoy escribiendo esto.

Lo esencial

Cuando se llama a la devolución de llamada de http.createServer, es cuando el servidor ha recibido todos los encabezados de la solicitud, pero es posible que los datos aún no se hayan recibido, por lo que tenemos que esperar. El objeto de solicitud http (una instancia de http.IncomingMessage) es en realidad una secuencia legible . En transmisiones legibles cada vez que llega un fragmento de datos, se emite un evento (suponiendo que haya registrado una devolución de llamada) y cuando todos los fragmentos han llegado se emite un evento. Aquí hay un ejemplo de cómo escuchas los eventos:data end

http.createServer((request, response) => {
  console.log('Now we have a http message with headers but no data yet.');
  request.on('data', chunk => {
    console.log('A chunk of data has arrived: ', chunk);
  });
  request.on('end', () => {
    console.log('No more data');
  })
}).listen(8080)

Convertir buffers en cadenas

Si intenta esto, notará que los trozos son amortiguadores . Si no está tratando con datos binarios y necesita trabajar con cadenas, sugiero usar el método request.setEncoding que hace que la secuencia emita cadenas interpretadas con la codificación dada y maneja los caracteres de varios bytes correctamente.

Trozos de búfer

Ahora probablemente no esté interesado en cada fragmento por sí mismo, por lo que en este caso probablemente desee almacenarlo de la siguiente manera:

http.createServer((request, response) => {
  const chunks = [];
  request.on('data', chunk => chunks.push(chunk));
  request.on('end', () => {
    const data = Buffer.concat(chunks);
    console.log('Data: ', data);
  })
}).listen(8080)

Aquí se usa Buffer.concat , que simplemente concatena todos los buffers y devuelve un gran buffer. También puede usar el módulo concat-stream que hace lo mismo:

const http = require('http');
const concat = require('concat-stream');
http.createServer((request, response) => {
  concat(request, data => {
    console.log('Data: ', data);
  });
}).listen(8080)

Analizando contenido

Si está intentando aceptar el envío POST de formularios HTML sin archivos o si está recibiendo llamadas jQuery ajax con el tipo de contenido predeterminado, entonces el tipo de contenido es application/x-www-form-urlencodedcon uft-8codificación. Puede usar el módulo de cadena de consulta para deserializarlo y acceder a las propiedades:

const http = require('http');
const concat = require('concat-stream');
const qs = require('querystring');
http.createServer((request, response) => {
  concat(request, buffer => {
    const data = qs.parse(buffer.toString());
    console.log('Data: ', data);
  });
}).listen(8080)

Si su tipo de contenido es JSON, simplemente puede usar JSON.parse en lugar de qs.parse .

Si está tratando con archivos o manejando un tipo de contenido multiparte, entonces en ese caso, debe usar algo como formidable que elimine todo el dolor de lidiar con él. Eche un vistazo a esta otra respuesta mía donde publiqué enlaces y módulos útiles para contenido de varias partes.

Tubería

Si no desea analizar el contenido, sino pasarlo a otro lugar, por ejemplo, envíelo a otra solicitud http como datos o guárdelo en un archivo, sugiero canalizarlo en lugar de almacenarlo en el búfer, ya que será menos código, maneja mejor la contrapresión, tomará menos memoria y en algunos casos más rápido.

Entonces, si desea guardar el contenido en un archivo:

 http.createServer((request, response) => {
   request.pipe(fs.createWriteStream('./request'));
 }).listen(8080)

Limitar la cantidad de datos

Como otras respuestas han señalado, tenga en cuenta que los clientes malintencionados pueden enviarle una gran cantidad de datos para bloquear su aplicación o llenar su memoria, para protegerlo y asegurarse de que descarta las solicitudes que emiten datos que pasan un cierto límite. Si no usa una biblioteca para manejar los datos entrantes. Sugeriría usar algo como el medidor de flujo que puede cancelar la solicitud si alcanza el límite especificado:

limitedStream = request.pipe(meter(1e7));
limitedStream.on('data', ...);
limitedStream.on('end', ...);

o

request.pipe(meter(1e7)).pipe(createWriteStream(...));

o

concat(request.pipe(meter(1e7)), ...);

Módulos NPM

Si bien describí anteriormente cómo puede usar el cuerpo de solicitud HTTP, simplemente para almacenar en búfer y analizar el contenido, sugiero usar uno de estos módulos en lugar de implementarlo por su cuenta, ya que probablemente manejarán mejor los casos extremos. Para expresar, sugiero usar body-parser . Para koa, hay un módulo similar .

Si no usa un marco, el cuerpo es bastante bueno.

Farid Nouri Neshat
fuente
Gracias, usé tu código y recibí misteriosos mensajes duplicados. ¿Podría ser que la variable requestse reutilice y request.on('end')se invoque varias veces? ¿Cómo puedo evitar eso?
Yan King Yin
No puedo decir por qué sin ver tu código. Tenga en cuenta que para cada solicitud, request.on('end', ...)se llamará.
Farid Nouri Neshat
Probablemente no esté relacionado con su código, estoy haciendo eventos enviados por el servidor y puede que lo haya estropeado ... su código funciona bien, gracias de todos modos :)
Yan King Yin
¿Cómo afecta esto el rendimiento en comparación con el procesamiento de una solicitud GET sin un controlador 'final', es decir, sin trozos de búfer?
JSON
1
Esta es la mejor respuesta a la pregunta. 🧐
montrealist
103

Aquí hay un contenedor sin marco muy simple basado en las otras respuestas y artículos publicados aquí:

var http = require('http');
var querystring = require('querystring');

function processPost(request, response, callback) {
    var queryData = "";
    if(typeof callback !== 'function') return null;

    if(request.method == 'POST') {
        request.on('data', function(data) {
            queryData += data;
            if(queryData.length > 1e6) {
                queryData = "";
                response.writeHead(413, {'Content-Type': 'text/plain'}).end();
                request.connection.destroy();
            }
        });

        request.on('end', function() {
            request.post = querystring.parse(queryData);
            callback();
        });

    } else {
        response.writeHead(405, {'Content-Type': 'text/plain'});
        response.end();
    }
}

Ejemplo de uso:

http.createServer(function(request, response) {
    if(request.method == 'POST') {
        processPost(request, response, function() {
            console.log(request.post);
            // Use request.post here

            response.writeHead(200, "OK", {'Content-Type': 'text/plain'});
            response.end();
        });
    } else {
        response.writeHead(200, "OK", {'Content-Type': 'text/plain'});
        response.end();
    }

}).listen(8000);
Mahn
fuente
¿No debería esta comprobación moverse a un middleware separado para que pueda verificar si hay solicitudes demasiado grandes en todas las solicitudes de publicación / colocación?
Pavel Nikolov
@PavelNikolov esto está destinado principalmente a los trabajos rápidos y sucios, de lo contrario, probablemente sea mejor usar Express como la respuesta aceptada aquí recomienda (que probablemente también se encarga de gestionar grandes solicitudes). Sin embargo, siéntase libre de modificarlo y "bifurcarlo" a su gusto.
Mahn
¿Qué pasa con el método .read ()? ¿Eso no es compatible con el módulo http? P.ej. response.read ()
BT
Oye, solo curiosidad: ¿por qué has colocado la carga útil en el objeto de respuesta (response.post) en lugar del objeto de solicitud?
Jotham
Buena pregunta de @Jotham ... No tengo idea de por qué no me di cuenta antes, pero no hay razón para que sea response.postmás lógico request.post. Actualicé la publicación.
Mahn
83

Será más limpio si codifica sus datos a JSON y luego los envía a Node.js.

function (req, res) {
    if (req.method == 'POST') {
        var jsonString = '';

        req.on('data', function (data) {
            jsonString += data;
        });

        req.on('end', function () {
            console.log(JSON.parse(jsonString));
        });
    }
}
Luis
fuente
1
Esto es lo que funcionó para mí. Resulta que las otras soluciones devolvieron una cadena que parecía JSON pero que no se analizó. En lugar de qs.parse(), JSON.parse()convirtió el cuerpo en algo utilizable. Ejemplo:, var post = JSON.parse(body);luego acceda a los datos con post.fieldname. (Moraleja de la historia, si estás confundido acerca de lo que estás viendo, ¡no te olvides typeof!)
wmassingham
12
Bueno, tenga en cuenta que debe intentar capturar la función JSON.parse porque si quiero bloquear su aplicación, simplemente envíe un cuerpo con texto sin formato.
ecarrizo
Debería usar request.setEncodingpara que esto funcione correctamente; de ​​lo contrario, es posible que no maneje caracteres no ASCII correctamente.
Farid Nouri Neshat
37

Para cualquiera que se pregunte cómo hacer esta tarea trivial sin instalar un marco web, logré hacer esto juntos. Apenas listo para la producción pero parece funcionar.

function handler(req, res) {
    var POST = {};
    if (req.method == 'POST') {
        req.on('data', function(data) {
            data = data.toString();
            data = data.split('&');
            for (var i = 0; i < data.length; i++) {
                var _data = data[i].split("=");
                POST[_data[0]] = _data[1];
            }
            console.log(POST);
        })
    }
}
Shawn Whinnery
fuente
Finalmente, una solución de TRABAJO COMPLETO para este problema extraño ... también la respuesta anterior ayudó mucho a entender por qué no había datos dentro de la solicitud cuando comienza la devolución de llamada ... ¡Muchas gracias!
luis-br
3
1) Esta respuesta supone que los datos son una cadena. Mala suposición, en un caso general. 2) Esta respuesta supone que los datos llegan en un fragmento. De lo contrario, dividir por '=' dará un resultado impredecible. Mala suposición, en un caso general.
Konstantin
@ Konstantin En realidad, esta respuesta supone que los datos son un Buffer. Mira esto. stackoverflow.com/questions/14551194/… También esto. millermedeiros.github.io/mdoc/examples/node_api/doc/…
Shawn Whinnery
16

Puede usar body-parserel middleware de análisis del cuerpo de Node.js.

Primera carga body-parser

$ npm install body-parser --save

Algún código de ejemplo

var express = require('express')
var bodyParser = require('body-parser')

var app = express()

app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())


app.use(function (req, res) {
  var post_data = req.body;
  console.log(post_data);
})

Puede encontrar más documentación aquí.

código fuente
fuente
9

Aquí es cómo puede hacerlo si usa formidable de nodo :

var formidable = require("formidable");

var form = new formidable.IncomingForm();
form.parse(request, function (err, fields) {
    console.log(fields.parameter1);
    console.log(fields.parameter2);
    // ...
});
Dmitry Efimenko
fuente
Tengo un problema con la ruta, cuando intento usar la ruta o la ruta + nombre para acceder al archivo con lwip.open (ruta o ruta + nombre
obtengo
7

Si prefiere usar Node.js puro, puede extraer datos POST como se muestra a continuación:

// Dependencies
const StringDecoder = require('string_decoder').StringDecoder;
const http = require('http');

// Instantiate the HTTP server.
const httpServer = http.createServer((request, response) => {
  // Get the payload, if any.
  const decoder = new StringDecoder('utf-8');
  let payload = '';

  request.on('data', (data) => {
    payload += decoder.write(data);
  });

  request.on('end', () => {
    payload += decoder.end();

    // Parse payload to object.
    payload = JSON.parse(payload);

    // Do smoething with the payload....
  });
};

// Start the HTTP server.
const port = 3000;
httpServer.listen(port, () => {
  console.log(`The server is listening on port ${port}`);
});

Oleksii Trekhleb
fuente
6

1) Instalar 'body-parser'desde npm.

2) Luego en tu app.ts

var bodyParser = require('body-parser');

3) entonces necesitas escribir

app.use(bodyParser.json())

en el módulo app.ts

4) ten en cuenta que incluyes

app.use(bodyParser.json())

en la parte superior o antes de cualquier declaración de módulo.

Ex:

app.use(bodyParser.json())
app.use('/user',user);

5) Luego use

var postdata = req.body;
Er Shubham Patidar
fuente
5

Si no desea agrupar sus datos junto con la datadevolución de llamada, siempre puede usar la readabledevolución de llamada de esta manera:

// Read Body when Available
request.on("readable", function(){
  request.body = '';
  while (null !== (request.body += request.read())){}
});

// Do something with it
request.on("end", function(){
  request.body //-> POST Parameters as String
});

Este enfoque modifica la solicitud entrante, pero tan pronto como termine su respuesta, la solicitud será recolectada de basura, por lo que no debería ser un problema.

Un enfoque avanzado sería verificar primero el tamaño del cuerpo, si tienes miedo de los cuerpos enormes.

Thomas Fankhauser
fuente
Una forma conveniente de hacerlo, pero ¿cómo "verifica primero el tamaño del cuerpo" de una manera que no pueda ser engañada por una solicitud maliciosa?
doug65536
requestes una secuencia normal de node.js, por lo que puede verificar la request.headerslongitud del cuerpo y cancelar la solicitud si es necesario.
Thomas Fankhauser
1
@ThomasFankhauser La longitud del cuerpo en el encabezado puede no ser el valor correcto o incluso presente. La forma correcta de hacerlo es cuando llega el cuerpo y lo está almacenando en el búfer, verifica el tamaño para asegurarse de que no supere el límite.
Farid Nouri Neshat
4

Hay múltiples formas de hacerlo. Sin embargo, la forma más rápida que conozco es usar la biblioteca Express.js con body-parser.

var express = require("express");
var bodyParser = require("body-parser");
var app = express();

app.use(bodyParser.urlencoded({extended : true}));

app.post("/pathpostdataissentto", function(request, response) {
  console.log(request.body);
  //Or
  console.log(request.body.fieldName);
});

app.listen(8080);

Eso puede funcionar para cadenas, pero cambiaría bodyParser.urlencoded a bodyParser.json si los datos POST contienen una matriz JSON.

Más información: http://www.kompulsa.com/how-to-accept-and-parse-post-requests-in-node-js/

nikodean2
fuente
4

Debe recibir los POSTdatos en fragmentos utilizandorequest.on('data', function(chunk) {...})

const http = require('http');

http.createServer((req, res) => {
    if (req.method == 'POST') {
        whole = ''
        req.on('data', (chunk) => {
            # consider adding size limit here
            whole += chunk.toString()
        })

        req.on('end', () => {
            console.log(whole)
            res.writeHead(200, 'OK', {'Content-Type': 'text/html'})
            res.end('Data received.')
        })
    }
}).listen(8080)

Debería considerar agregar un límite de tamaño en la posición indicada como lo sugiere jh .

Zaz
fuente
¿Es esto más susceptible a un ataque lento de loris?
Nodejs es menos susceptible a loris lento que, por ejemplo, php, porque no crea un objeto de sesión grande alrededor de cada conexión http. Sin embargo, parece que este código aún podría introducir una vulnerabilidad de loris lenta. Esto podría evitarse con una setTimeoutque finalice la conexión después de un cierto período de tiempo, si la solicitud completa no se recibe dentro de esa ventana.
Gershom
4

Express v4.17.0

app.use(express.urlencoded( {extended: true} ))
antílope
fuente
3

Si está utilizando Express.js , antes de poder acceder a req.body, debe agregar el middleware bodyParser:

app.use(express.bodyParser());

Entonces puedes pedir

req.body.user
PatricioS
fuente
La mayoría del middleware (como bodyParser) ya no está incluido con Express y debe instalarse por separado. Vea la respuesta de @ nikodean2 arriba para obtener una respuesta más actual
Jeff Collier,
app.use (bodyParser ()); funciona pero me está dando mensajes de error rojos de desaprobación
Chris Allinson
2

Y si no desea utilizar todo el marco como Express, pero también necesita diferentes tipos de formularios, incluidas las cargas, entonces la formalina puede ser una buena opción.

Está listado en los módulos Node.js

Pavel Koryagin
fuente
1

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 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.

Código fuente relacionado:

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);
usuario203687
fuente
1

Para aquellos que usan carga POST binaria sin codificar, pueden usar:

cliente:

var xhr = new XMLHttpRequest();
xhr.open("POST", "/api/upload", true);
var blob = new Uint8Array([65,72,79,74]); // or e.g. recorder.getBlob()
xhr.send(blob);

servidor:

var express = require('express');
var router = express.Router();
var fs = require('fs');

router.use (function(req, res, next) {
  var data='';
  req.setEncoding('binary');
  req.on('data', function(chunk) {
    data += chunk;
  });

  req.on('end', function() {
    req.body = data;
    next();
  });
});

router.post('/api/upload', function(req, res, next) {
  fs.writeFile("binaryFile.png", req.body, 'binary', function(err) {
    res.send("Binary POST successful!");
  });
});
lukyer
fuente
1

Puede usar el middleware express , que ahora tiene incorporado un analizador de cuerpo. Esto significa que todo lo que necesita hacer es lo siguiente:

import express from 'express'

const app = express()

app.use(express.json())

app.post('/thing', (req, res) => {
  console.log(req.body) // <-- this will access the body of the post
  res.sendStatus(200)
})

Ese ejemplo de código es ES6 con Express 4.16.x

Gran dinero
fuente
0

puede extraer el parámetro de publicación sin usar express.

1: nmp install multiparty

2: importar multiparte. comovar multiparty = require('multiparty');

3: `

if(req.method ==='POST'){
   var form = new multiparty.Form();
   form.parse(req, function(err, fields, files) {
      console.log(fields['userfile1'][0]);
    });
    }

4: y HTML FORM IS.

<form method=POST enctype=multipart/form-data>
<input type=text name=userfile1><br>
<input type=submit>
</form>

Espero que esto funcione para tí. Gracias.

Maneesh Singh
fuente
0

Limite el tamaño de la POST para evitar inundar su aplicación de nodo. Hay un excelente módulo de cuerpo sin procesar , adecuado tanto para Express como para Connect, que puede ayudarlo a limitar la solicitud por tamaño y longitud.

EricSonaron
fuente
0

Si implica la carga de un archivo, el navegador generalmente lo envía como un "multipart/form-data"tipo de contenido. Puedes usar esto en tales casos

var multipart = require('multipart');
multipart.parse(req)

Referencia 1

Referencia 2

usuario3526
fuente
0

En campos de formulario como estos

   <input type="text" name="user[name]" value="MyName">
   <input type="text" name="user[email]" value="[email protected]">

algunas de las respuestas anteriores fallarán porque solo admiten datos planos.

Por ahora estoy usando la respuesta Casey Chu pero con el "qs" en lugar del módulo "querystring". Este es también el módulo que utiliza "body-parser" . Entonces, si desea datos anidados, debe instalar qs.

npm install qs --save

Luego reemplace la primera línea como:

//var qs = require('querystring');
var qs = require('qs'); 

function (request, response) {
    if (request.method == 'POST') {
        var body = '';

        request.on('data', function (data) {
            body += data;

            // Too much POST data, kill the connection!
            // 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB
            if (body.length > 1e6)
                request.connection.destroy();
        });

        request.on('end', function () {
            var post = qs.parse(body);
            console.log(post.user.name); // should work
            // use post['blah'], etc.
        });
    }
}
Geza Turi
fuente
0

Puede enviar y obtener fácilmente la respuesta de la solicitud POST utilizando "Solicitud - Cliente HTTP simplificado" y Promesa Javascript.

var request = require('request');

function getData() {
    var options = {
        url: 'https://example.com',
        headers: {
            'Content-Type': 'application/json'
        }
    };

    return new Promise(function (resolve, reject) {
        var responseData;
        var req = request.post(options, (err, res, body) => {
            if (err) {
                console.log(err);
                reject(err);
            } else {
                console.log("Responce Data", JSON.parse(body));
                responseData = body;
                resolve(responseData);
            }
        });
    });
}
Kaveesha Baddage
fuente
0

Debe usar bodyParser () si desea que los datos del formulario estén disponibles en req.body. body-parser analiza su solicitud y la convierte a un formato desde el cual puede extraer fácilmente la información relevante que pueda necesitar.

Por ejemplo, supongamos que tiene un formulario de registro en su interfaz. Lo está completando y solicita al servidor que guarde los detalles en alguna parte.

Extraer el nombre de usuario y la contraseña de su solicitud es tan simple como a continuación si usa body-parser.

…………………………………………………….

var loginDetails = {

username : request.body.username,

password : request.body.password

};
Rubin Bhandari
fuente
0

ONE LINER sin MIDDLEWARE
Si publica los siguientes datos,
'name':'ABC'
puede analizarlos utilizando el siguiente liner,

require('url').parse(req.url, true).query.name
Hardik Trivedi
fuente