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?

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

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

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.


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

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

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.


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


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

20

Agrega tu app.js

antes de la llamada del enrutador

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

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.


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

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.


8

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



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

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


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.


5

en Express 4, es realmente simple

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

app.use(express.json()) 

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

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.


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

3

Lo resolví con:

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

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

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

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

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

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

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 )


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


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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.