Node.js: obtiene el cuerpo de la solicitud sin procesar usando Express

Cuando uso Express, y mi código es:

app.use(express.bodyParser()); 

¿Cómo obtendría el cuerpo de solicitud sin procesar ?

Edición 2: la versión 1.15.2 del módulo analizador corporal introduce el modo sin formato, que devuelve el cuerpo como un búfer . Por defecto, también maneja automáticamente desinflar y descomprimir gzip. Ejemplo de uso:

 var bodyParser = require('body-parser'); app.use(bodyParser.raw(options)); app.get(path, function(req, res) { // req.body is a Buffer object }); 

Por defecto, el objeto de options tiene las siguientes opciones predeterminadas:

 var options = { inflate: true, limit: '100kb', type: 'application/octet-stream' }; 

Si desea que su analizador sin formato analice otros tipos MIME que no sean application/octet-stream , deberá cambiarlo aquí. También admitirá la coincidencia de comodines como */* o */application .


Nota: La siguiente respuesta es para versiones anteriores a Express 4, donde el middleware aún estaba incluido con el marco. El equivalente moderno es el módulo de analizador de cuerpo , que debe instalarse por separado.

La propiedad rawBody en Express estuvo una vez disponible, pero se eliminó desde la versión 1.5.1. Para obtener el cuerpo de solicitud sin procesar, debe colocar algún middleware antes de usar bodyParser. También puede leer un debate sobre GitHub aquí .

 app.use(function(req, res, next) { req.rawBody = ''; req.setEncoding('utf8'); req.on('data', function(chunk) { req.rawBody += chunk; }); req.on('end', function() { next(); }); }); app.use(express.bodyParser()); 

Ese middleware leerá de la secuencia de datos real y lo almacenará en la propiedad rawBody de la solicitud. A continuación, puede acceder al cuerpo sin procesar de esta manera:

 app.post('/', function(req, res) { // do something with req.rawBody // use req.body for the parsed body }); 

Editar: parece que este método y bodyParser se niegan a coexistir, ya que uno consumirá el flujo de solicitud antes que el otro, lo que generará el segundo que nunca se disparará, por lo tanto, nunca llamará a next() y colgará la aplicación.

La solución más simple probablemente sería modificar la fuente de bodyParser, que se encontraría en la línea 57 del analizador JSON de Connect. Así es como se vería la versión modificada.

 var buf = ''; req.setEncoding('utf8'); req.on('data', function(chunk){ buf += chunk }); req.on('end', function() { req.rawBody = buf; var first = buf.trim()[0]; ... }); 

Encontrarías el archivo en esta ubicación:

/node_modules/express/node_modules/connect/lib/middleware/json.js .

Obtuve una solución que funciona bien con bodyParser, usando la verify callback en bodyParser. En este código, lo estoy usando para obtener un sha1 del contenido y obtener el cuerpo sin procesar.

 app.use(bodyParser.json({ verify: function(req, res, buf, encoding) { // sha1 content var hash = crypto.createHash('sha1'); hash.update(buf); req.hasha = hash.digest('hex'); console.log("hash", req.hasha); // get rawBody req.rawBody = buf.toString(); console.log("rawBody", req.rawBody); } })); 

Soy nuevo en Node.js y express.js (¡comencé ayer, literalmente!) Así que me gustaría escuchar comentarios sobre esta solución.

TENGA CUIDADO con esas otras respuestas, ya que no funcionarán correctamente con bodyParser si también está buscando admitir json, urlencoded, etc. Para que funcione con bodyParser, debe condicionar su controlador para que solo se registre en el encabezado Content-Type ( s) te importa, al igual que bodyParser sí mismo.

Para obtener el contenido de cuerpo sin procesar de una solicitud con Content-Type: "text/plain" en req.rawBody puede hacer:

 app.use(function(req, res, next) { var contentType = req.headers['content-type'] || '' , mime = contentType.split(';')[0]; if (mime != 'text/plain') { return next(); } var data = ''; req.setEncoding('utf8'); req.on('data', function(chunk) { data += chunk; }); req.on('end', function() { req.rawBody = data; next(); }); }); 

Esta es una variación de la respuesta del hexacianuro anterior. Este middleware también maneja el evento ‘data’ pero no espera a que se consumn los datos antes de llamar a ‘next’. De esta manera, tanto este middleware como bodyParser pueden coexistir, consumiendo la transmisión en paralelo.

 app.use(function(req, res, next) { req.rawBody = ''; req.setEncoding('utf8'); req.on('data', function(chunk) { req.rawBody += chunk; }); next(); }); app.use(express.bodyParser()); 

Esta solución funcionó para mí:

 var rawBodySaver = function (req, res, buf, encoding) { if (buf && buf.length) { req.rawBody = buf.toString(encoding || 'utf8'); } } app.use(bodyParser.json({ verify: rawBodySaver })); app.use(bodyParser.urlencoded({ verify: rawBodySaver, extended: true })); app.use(bodyParser.raw({ verify: rawBodySaver, type: '*/*' })); 

Cuando uso la solución con req.on('data', function(chunk) { }); no funciona en el cuerpo de solicitud fragmentado.

Intereting Posts