¿Cómo acceder al cuerpo de la solicitud al POSTAR usando Node.js y Express?

175

Tengo el siguiente código Node.js:

var express = require('express');
var app = express.createServer(express.logger());
app.use(express.bodyParser());

app.post('/', function(request, response) {
    response.write(request.body.user);
    response.end();
});

Ahora si publico algo como:

curl -d user=Someone -H Accept:application/json --url http://localhost:5000

Me pongo Someonecomo se esperaba. Ahora, ¿qué pasa si quiero obtener el cuerpo completo de la solicitud? Intenté hacerlo, response.write(request.body)pero Node.js arroja una excepción que dice "el primer argumento debe ser una cadena o Buffer " y luego pasa a un "bucle infinito" con una excepción que dice " No se pueden establecer encabezados después de que se envían "; Esto también es cierto incluso si lo hice var reqBody = request.body;y luego escribir response.write(reqBody).

¿Cuál es el problema aquí?

Además, ¿puedo obtener la solicitud sin procesar sin usar express.bodyParser()?

El cielo azul
fuente
Parece que hay algo con response.write(reqBody); cuando uso las response.send(reqBody)cosas funcionan bien ... y sí, uso response.enddespués response.write.
TheBlueSky

Respuestas:

161

Express 4.0 y superior:

$ npm install --save body-parser

Y luego en su aplicación de nodo:

const bodyParser = require('body-parser');
app.use(bodyParser);

Express 3.0 y abajo:

Intente pasar esto en su llamada cURL:

--header "Content-Type: application/json"

y asegurándose de que sus datos estén en formato JSON:

{"user":"someone"}

Además, puede usar console.dir en su código node.js para ver los datos dentro del objeto como en el siguiente ejemplo:

var express = require('express');
var app = express.createServer();

app.use(express.bodyParser());

app.post('/', function(req, res){
    console.dir(req.body);
    res.send("test");
}); 

app.listen(3000);

Esta otra pregunta también podría ayudar: ¿Cómo recibir JSON en la solicitud POST express node.js?

Si no desea utilizar bodyParser, consulte esta otra pregunta: https://stackoverflow.com/a/9920700/446681

Héctor Correa
fuente
Intenté usarlo, curl -d {"user":"Someone"} -H "Content-Type: application/json" --url http://localhost:5000pero me estaba dando el error " Token inesperado u ", por eso cambié a la llamada mencionada en mi publicación original.
TheBlueSky
Estoy marcando esto como respuesta debido al enlace stackoverflow.com/a/9920700/446681
TheBlueSky
40
express.bodyParser()está en desuso en Express 4.x. Utilice npmjs.org/package/body-parser en su lugar.
Luc
@TheBlueSky, la razón por la que obtuviste "Token U inesperado" fue porque el shell consumió tus comillas dobles. Lo mismo sucede si lo haces echo any"thing". Los datos que está publicando deben estar entre comillas para evitar que esto suceda.
Tom Fenech
11
Desde express 4.16.0 o superior es posible usar express.json () en app.use () de esta manera => app.use (express.json ());
Mitro
187

A partir de express v4.16 no hay necesidad de requerir ningún módulo adicional, solo use el middleware JSON incorporado :

app.use(express.json())

Me gusta esto:

const express = require('express')

app.use(express.json())    // <==== parse request body as JSON

app.listen(8080)

app.post('/test', (req, res) => {
  res.json({requestBody: req.body})  // <==== req.body will be a parsed JSON object
})

Nota: body-parserde esto depende, ya está incluido con express.

Tampoco olvides enviar el encabezado Content-Type: application/json

rustyx
fuente
14
Gracias, esta es la mejor respuesta para 4.16+ entonces. No hay otras dependencias y funciona como un encanto!
codepleb
1
La mejor / única solución que pude encontrar que no necesita el analizador corporal
Mote Zart
41

A partir de Express 4, el siguiente código parece hacer el truco. Tenga en cuenta que deberá instalar body-parserusando npm.

var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({ extended: false }));


app.listen(8888);

app.post('/update', function(req, res) {
    console.log(req.body); // the posted data
});
Walter Roman
fuente
29
Para analizar los cuerpos json es necesario agregar la siguiente líneaapp.use(bodyParser.json())
Camilo Silva el
1
@ cml.co ¿hay alguna razón app.use(bodyParser.urlencoded({ extended: true })está también requiere? Estoy publicando un documento bastante complejo como JSON en la solicitud, y extended: falseno funcionó. Solo cuando lo configuro en verdadero, la solicitud se analiza correctamente.
Usuario web
3
Solo una nota. Tuve que usar app.use(bodyParser.urlencoded({ extended: true }));AND app.use(bodyParser.json())para obtener datos json en una configuración de servidor AWS Linux con NodeJS y Express.
David
24
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json())

var port = 9000;

app.post('/post/data', function(req, res) {
    console.log('receiving data...');
    console.log('body is ',req.body);
    res.send(req.body);
});

// start the server
app.listen(port);
console.log('Server started! At http://localhost:' + port);

Esto te ayudara. Supongo que está enviando el cuerpo en json.

Gautama
fuente
Siempre me olvido de agregar el bodyParser.json () bit x_x ¡gracias!
Jonny Asmar
14

Para 2019, no necesita instalar body-parser.

Puedes usar:

var express = require('express');
var app = express();
app.use(express.json())
app.use(express.urlencoded({extended: true}))
app.listen(8888);
app.post('/update', function(req, res) {
    console.log(req.body); // the posted data
});
Shivam Gupta
fuente
8

Esto puede lograrse sin body-parserla dependencia, así, escuchar request:datay request:endy devolver la respuesta en el extremo de la solicitud, se refieren a continuación ejemplo de código. ref: https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/#request-body

var express = require('express');
var app = express.createServer(express.logger());

app.post('/', function(request, response) {

    // push the data to body
    var body = [];
    request.on('data', (chunk) => {
      body.push(chunk);
    }).on('end', () => {
      // on end of data, perform necessary action
      body = Buffer.concat(body).toString();
      response.write(request.body.user);
      response.end();
    });
});
Manivannan
fuente
3

Prueba esto:

response.write(JSON.stringify(request.body));

Eso tomará el objeto que bodyParserha creado para usted y lo convertirá en una cadena y lo escribirá en la respuesta. Si desea el cuerpo exacto de la solicitud (con el mismo espacio en blanco, etc.), necesitará datay endescuchas adjuntos a la solicitud antes y acumulará la cadena fragmento por fragmento como puede ver en el código fuente de análisis json de connect .

Peter Lyons
fuente
1

Lo que dice haber "intentado hacer" es exactamente lo que escribió en el código que funciona "como se esperaba" cuando lo invoca con curl.

El error que está recibiendo no parece estar relacionado con ninguno de los códigos que nos ha mostrado.

Si desea obtener la solicitud de prima, manipuladores en el set requestpara las datay endlos acontecimientos (y, por supuesto, eliminar las invocaciones de express.bodyParser()). Tenga en cuenta que los dataeventos ocurrirán en fragmentos, y que a menos que establezca una codificación para el dataevento, esos fragmentos serán buffers, no cadenas.

ebohlman
fuente
eso fue un error de copiar y pegar; Quise decir request.bodyy no request.body.user, y lo corregí ahora. Por cierto, var reqBody = request.body;era correcto y sigue siendo correcto, y cuando lo pruebes obtendrás el error que estoy recibiendo. De todos modos, ¿puede dar un ejemplo sobre cómo configurar el controlador request; Parece que no lo encuentro en la guía express.
TheBlueSky
1

Si eres lo suficientemente flojo como para leer fragmentos de datos de publicaciones. simplemente puede pegar debajo de las líneas para leer json.

A continuación se muestra para TypeScript que también se puede hacer para JS.

app.ts

 import bodyParser from "body-parser";
 // support application/json type post data
 this.app.use(bodyParser.json());
 // support application/x-www-form-urlencoded post data
 this.app.use(bodyParser.urlencoded({ extended: false }));

En uno de sus controladores que recibe llamadas POST, use como se muestra a continuación

userController.ts

 public async POSTUser(_req: Request, _res: Response) {
   try {
          const onRecord = <UserModel>_req.body;
           /* Your business logic */
           _res.status(201).send("User Created");
        }
    else{
           _res.status(500).send("Server error");
           }        
   };

_req.body debería analizar sus datos json en su modelo TS.

Shujaath Khan
fuente
1
No estoy seguro de si estás tratando de alentar o desalentar a las personas a usar tu respuesta llamándolas perezosas :)
TheBlueSky
1

Soy absolutamente nuevo en JS y ES, pero lo que parece funcionar para mí es solo esto:

JSON.stringify(req.body)

¡Avísame si hay algo malo en ello!

Balintn
fuente
exactamente lo que necesitaba
Josef Henn
0

Instale Body Parser con el siguiente comando

$ npm install --save body-parser

Configurar Body Parser

const bodyParser = require('body-parser');
app.use(bodyParser);
app.use(bodyParser.json()); //Make sure u have added this line
app.use(bodyParser.urlencoded({ extended: false }));
Arun Abimanyu
fuente
-3

Utiliza el siguiente código para registrar datos de publicación:

router.post("/users",function(req,res){
    res.send(JSON.stringify(req.body, null, 4));
});
Chandra Kumar
fuente
2
La respuesta dada es incompleta sin incluir el módulo body-parser.
gramcha