Express.js req.body undefined

291

Tengo esto como configuración de mi servidor Express

app.use(app.router); 
app.use(express.cookieParser());
app.use(express.session({ secret: "keyboard cat" }));
app.set('view engine', 'ejs');
app.set("view options", { layout: true });
//Handles post requests
app.use(express.bodyParser());
//Handles put requests
app.use(express.methodOverride());

Pero aún así, cuando solicito req.body.somethingen mis rutas, aparece un error que lo señala body is undefined. Aquí hay un ejemplo de una ruta que usa req.body:

app.post('/admin', function(req, res){
    console.log(req.body.name);
});

Leí que este problema es causado por la falta de, app.use(express.bodyParser());pero como puede ver, lo llamo antes de las rutas.

¿Cualquier pista?

Masiar
fuente

Respuestas:

296

Debe asegurarse de definir todas las configuraciones ANTES de definir rutas. Si lo hace, puede continuar usándolo express.bodyParser().

Un ejemplo es el siguiente:

var express = require('express'),
    app     = express(),
    port    = parseInt(process.env.PORT, 10) || 8080;

app.configure(function(){
  app.use(express.bodyParser());
  app.use(app.router);
});

app.listen(port);

app.post("/someRoute", function(req, res) {
  console.log(req.body);
  res.send({ status: 'SUCCESS' });
});
Mark Bonano
fuente
9
Esto funcionó para mí. Nota: Desafortunadamente, algunos tutoriales por ahí tienen personas (como yo) que ponen rutas antes de app.configure (). En mi caso, esto fue en forma de app.get / post, etc., y un require () que los incluye.
Bendman
1
Muchas gracias, estuve solucionando este problema todo el día.
jfplataroti
11
a partir de express 4, se elimina app.use (app.router). por favor vea los documentos github.com/visionmedia/express/wiki/New-features-in-4.x
Jonathan Ong
15
a partir de express 4, los middlewares como bodyParser ya no se incluyen con Express y deben instalarse por separado. Puede encontrar más información aquí: github.com/senchalabs/connect#middleware .
andrea.rinaldi
2
Gracias. Esta respuesta tiene más de 2 años y sigue ayudando a las personas en problemas :)
Lorenzo Marcon
275

Las últimas versiones de Express (4.x) han desagregado el middleware del framework central. Si necesita un analizador corporal, debe instalarlo por separado

npm install body-parser --save

y luego haz esto en tu código

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

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())
Arrendajo
fuente
2
Recientemente actualicé para expresar 4.x. Inicialmente cuando intentaba registrar req.body me mostraba indefinido. Una vez que instalé y utilicé body-parser, me da los valores req.body esperados. :)
Alok Adhao
Encontré esto útil al tratar de averiguar por qué mis solicitudes POST no funcionaban con json-server.
freethebees
Me salvó el día, especialmente la parte 'app.use (bodyParser.json ())'. Gracias hermano ! : D
neaGaze
¡Esta debería ser la respuesta aceptada porque funciona totalmente para Express 4! ¡Gracias Señor!
Combine el
2
app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()) me salvó !!
Pramesh Bajracharya
71

No. Necesitas usar app.use(express.bodyParser())antes app.use(app.router). De hecho, app.use(app.router)debería ser lo último que llames.

danmactough
fuente
Incluso moverse app.use(app.router)bajo las .usellamadas no resuelve el problema :(.
Masiar
Ok, después de un poco de lucha, lo resolví usando en app.use(require('connect').bodyParser());lugar de app.use(express.bodyParser());.
Masiar
sí, la respuesta es verdadera incluso cuando se usa var router=express.Router();
Istiaque Ahmed
1
Adenda ligero, aún debe llamar middleware de gestión de errores después de la app.router
nave
BENDIGA ESTE COMENTARIO
Ke Ke
40

Primero asegúrese de haber instalado el módulo npm llamado 'body-parser' llamando a:

npm install body-parser --save

Luego, asegúrese de haber incluido las siguientes líneas antes de llamar a las rutas

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

app.use(bodyParser.json());
Ankit kaushik
fuente
Si está utilizando express.json, entonces ¿por qué importar body-parser?
SanSolo
38

Express 4, tiene un analizador de cuerpo incorporado. No es necesario instalar un analizador de cuerpo por separado. Entonces a continuación funcionará:

export const app = express();
app.use(express.json());
TechTurtle
fuente
37

El tipo de contenido en el encabezado de solicitud es realmente importante, especialmente cuando publica los datos de curl o cualquier otra herramienta.

Asegúrese de estar usando algo como application / x-www-form-urlencoded, application / json u otros, depende de los datos de su publicación. Dejar este campo vacío confundirá Express.

Kevin Xue
fuente
12
+1 Este fue el problema para mí. Estaba usando Postman para Chrome para probar una API JSON integrada en REST, pero el objeto recibido por Express estaba vacío cada vez. Resulta que Postman por defecto no agrega automáticamente el encabezado 'Content-Type: application / json' incluso si selecciona raw> json.
Jordan
@ Jordan +1 Gracias por señalar esto. De hecho, acabo de revisar mis encabezados y veo que todavía está configurado en 'text / plain' a pesar de que seleccioné 'json'.
Ingeniero
Ugh ... 7 años después y esto sigue siendo lo que me está tropezando ...
Shaun314
33

Como ya se publicó bajo un comentario, lo resolví usando

app.use(require('connect').bodyParser());

en vez de

app.use(express.bodyParser());

Todavía no sé por qué lo simple express.bodyParser()no funciona ...

Masiar
fuente
1
@Masiar Esto no está funcionando para mí. Estoy usando expressjs 4 y obtengo un error como este. Error: No se puede encontrar el módulo 'conectar'
Jeyarathnem Jeyachanthuru
1
@JeyTheva mine es una solución bastante antigua, por lo tanto, las cosas pueden haber cambiado mientras tanto. Le sugiero que intente instalar el connectmódulo a través npm install connecty vuelva a intentarlo. Esto es lo único que se me ocurre al leer el resultado de su error.
Masiar
44
Aquí está la última documentación para resolver este problema: npmjs.com/package/body-parser Para otros que experimentan este problema "post express 4", lo que funcionó para mí fue configurar el Content-Typeencabezado application/json.
Grant Eagon
3
Aquí está la última documentación para resolver este problema: npmjs.com/package/body-parser Después de instalar body-parser, todavía no funcionó. Lo que funcionó fue configurar el Content-Typeencabezado application/jsoncuando estaba haciendo mi solicitud.
Grant Eagon
1
application/jsonvs text/jsonen la solicitud funciona, como lo sugiere @GrantEagon.
Strider
21
// Require body-parser (to receive post data from clients)

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

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

// parse application/json

app.use(bodyParser.json())
RANJAN CENIZO
fuente
20

Agrega tu app.js

antes de la llamada del enrutador

const app = express();
app.use(express.json());
abdesselam
fuente
2
me salvaste el día hombre! La clave es añadir la línea antes de que el enrutador de llamada
ubaldisney
Esta cosa me salvó. Gracias :)
Farrukh Faizy
12

Parece que el analizador de cuerpo ya no se envía con express. Es posible que tengamos que instalarlo por separado.

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

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())

// parse application/vnd.api+json as json
app.use(bodyParser.json({ type: 'application/vnd.api+json' }))
app.use(function (req, res, next) {
console.log(req.body) // populated!

Consulte la página de git https://github.com/expressjs/body-parser para obtener más información y ejemplos.

Praneesh
fuente
1
Este parece ser el nuevo formato Express 4.x y funcionó para mí. El express.bodyParser () mencionado en otras respuestas no funciona en 4.x.
DustinB
10

En caso de que alguien se encuentre con el mismo problema que estaba teniendo; Estoy usando un prefijo de URL como

http://example.com/api/

que se configuró con el enrutador

app.use('/api', router); 

y luego tuve lo siguiente

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

Lo que solucionó mi problema fue colocar la configuración del bodyparser arriba app.use('/api', router);

Final

// setup bodyparser
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));

//this is a fix for the prefix of example.com/api/ so we dont need to code the prefix in every route
    app.use('/api', router); 
Jeff Beagley
fuente
9

express.bodyParser () necesita que se le diga qué tipo de contenido es el que está analizando. Por lo tanto, debe asegurarse de que cuando ejecute una solicitud POST, incluya el encabezado "Tipo de contenido". De lo contrario, bodyParser podría no saber qué hacer con el cuerpo de su solicitud POST.

Si está utilizando curl para ejecutar una solicitud POST que contiene algún objeto JSON en el cuerpo, se vería así:

curl -X POST -H "Content-Type: application/json" -d @your_json_file http://localhost:xxxx/someRoute

Si usa otro método, solo asegúrese de establecer ese campo de encabezado usando la convención apropiada.

ab107
fuente
8

Use app.use (bodyparser.json ()); antes de enrutar. //. app.use ("/ api", rutas);

usuario1614168
fuente
7

Puede intentar agregar esta línea de código en la parte superior (después de sus declaraciones de requerimiento):

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

En cuanto a las razones de por qué funciona, consulte los documentos: https://www.npmjs.com/package/body-parser#bodyparserurlencodedoptions

Anthony Cantellano
fuente
Quiero decir, tu respuesta es correcta, pero no es diferente a las demás.
dwjohnston
7

La mayoría de las veces, req.body no está definido debido a que falta el analizador JSON

const express = require('express');
app.use(express.json());

podría faltar para el analizador de cuerpo

const bodyParser  = require('body-parser');
app.use(bodyParser.urlencoded({extended: true}));

y a veces no está definido debido al origen de los cros, así que agrégalos

const cors = require('cors');
app.use(cors())
rey neo
fuente
5

Esto me ocurrió hoy. Ninguna de las soluciones anteriores funciona para mí. Pero un poco de google me ayudó a resolver este problema. Estoy codificando para el servidor de terceros wechat.

Las cosas se vuelven un poco más complicadas cuando su aplicación node.js requiere leer datos POST de transmisión, como una solicitud de un cliente REST. En este caso, la propiedad de la solicitud "legible" se establecerá en verdadera y los datos POST deben leerse en fragmentos para recopilar todo el contenido.

http://www.primaryobjects.com/CMS/Article144

spikeyang
fuente
la publicación menciona el envío del formulario HTML como diferente de la solicitud del cliente REST. ¿No son ambas solicitudes http? entonces, ¿POST es el único caso que requiere transmisión?
j10
5

Perdido mucho tiempo:

Dependiendo del tipo de contenido en la solicitud de su cliente,
el servidor debe tener una aplicación diferente, a continuación, use.) ():

app.use(bodyParser.text({ type: 'text/html' }))
app.use(bodyParser.text({ type: 'text/xml' }))
app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }))
app.use(bodyParser.json({ type: 'application/*+json' }))

Fuente: https://www.npmjs.com/package/body-parser#bodyparsertextoptions

Ejemplo:

Para mí, en el lado del cliente, tenía debajo del encabezado:

Content-Type: "text/xml"

Entonces, en el lado del servidor, usé:

app.use(bodyParser.text({type: 'text/xml'}));

Entonces, req.body funcionó bien.

Manohar Reddy Poreddy
fuente
5

en Express 4, es realmente simple

const app = express()
const p = process.env.PORT || 8082

app.use(express.json()) 
Gerardo Bautista
fuente
4

Para trabajar, necesita app.use (app.router) después de app.use (express.bodyParser ()) , así:

app.use(express.bodyParser())
   .use(express.methodOverride())
   .use(app.router);
HenioJR
fuente
1
Su comentario y fragmento de código son contradictorios. En primer lugar decir que usted tiene que utilizar app.useel app.routerantes express.bodyParser, pero su código indica claramente son más de las. Entonces, ¿cuál es?
Levi Roberts
1
Lo siento. Debe usar app.router después de express.bodyParser.
HenioJR
1
Gracias @LeviRoberts
HenioJR
4
var bodyParser = require('body-parser');
app.use(bodyParser.json());

Esto me salvó el día.

isdot
fuente
4

Este problema puede deberse a que no ha utilizado body-parser ( enlace )

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

var app = express();
app.use(bodyParser.json());
Arindam
fuente
3

Lo resolví con:

app.post('/', bodyParser.json(), (req, res) => {//we have req.body JSON
});
Kkkk Kkkk
fuente
3

Esta también es una posibilidad : asegúrese de escribir este código antes de la ruta en su archivo app.js (o index.js).

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
Inamur Rahman
fuente
2

Puede usar el analizador corporal exprés.

var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
Kuldeep Mishra
fuente
2

La última versión de Express ya tiene incorporado el analizador de cuerpo. Entonces puedes usar:

const express = require('express);
... 
app.use(express.urlencoded({ extended: false }))
.use(express.json());
LEMUEL ADANE
fuente
1

En caso de que publique un mensaje SOAP, debe usar un analizador de cuerpo sin procesar:

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

app.use(bodyParser.raw({ type: 'text/xml' }));
opewix
fuente
1

Basándose en @ kevin-xue, dijo, el tipo de contenido debe ser declarado. En mi caso, esto solo ocurría con IE9 porque XDomainRequest no establece un tipo de contenido , por lo que bodyparser y expressjs ignoraban el cuerpo de la solicitud.

Lo solucioné estableciendo el tipo de contenido explícitamente antes de pasar la solicitud al analizador de cuerpo, de esta manera:

app.use(function(req, res, next) {
    // IE9 doesn't set headers for cross-domain ajax requests
    if(typeof(req.headers['content-type']) === 'undefined'){
        req.headers['content-type'] = "application/json; charset=UTF-8";
    }
    next();
})
.use(bodyParser.json());
Purpletonic
fuente
1

Gracias a @spikeyang por la excelente respuesta (proporcionada a continuación). Después de leer el artículo sugerido adjunto a la publicación, decidí compartir mi solución.

¿Cuándo usar?

La solución requería que usaras el enrutador rápido para disfrutarlo ... así que: si has intentado usar la respuesta aceptada sin suerte, solo usa copiar y pegar esta función:

function bodyParse(req, ready, fail) 
{
    var length = req.header('Content-Length');

    if (!req.readable) return fail('failed to read request');

    if (!length) return fail('request must include a valid `Content-Length` header');

    if (length > 1000) return fail('this request is too big'); // you can replace 1000 with any other value as desired

    var body = ''; // for large payloads - please use an array buffer (see note below)

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

    req.on('end', function () 
    {
        ready(body);
    });
}

y lo llaman así:

bodyParse(req, function success(body)
{

}, function error(message)
{

});

NOTA: Para cargas grandes, utilice un búfer de matriz ( más @ MDN )

ymz
fuente
El paquete bodyParser se usa comúnmente y traduce la carga útil en un objeto body. como se proporciona en otras respuestas
Schuere
1

Si está utilizando alguna herramienta externa para realizar la solicitud, asegúrese de agregar el encabezado:

Content-Type: application/json

Inc33
fuente
Este me ayudó, estaba trabajando con Postman, gracias amigo.
R. Gurung