¿Cómo recuperar los parámetros de consulta POST?

768

Aquí está mi forma simple:

<form id="loginformA" action="userlogin" method="post">
    <div>
        <label for="email">Email: </label>
        <input type="text" id="email" name="email"></input>
    </div>
<input type="submit" value="Submit"></input>
</form>

Aquí está mi código Express.js /Node.js:

app.post('/userlogin', function(sReq, sRes){    
    var email = sReq.query.email.;   
}

Lo intenté sReq.query.emailo sReq.query['email']o sReq.params['email'], etc. Ninguno de ellos funciona. Todos regresan undefined.

Cuando cambio a obtener una llamada, funciona, así que ... ¿alguna idea?

murvinlai
fuente
33
SEGURIDAD : todos los que utilicen las bodyParser()respuestas aquí también deben leer la respuesta de @SeanLynch a continuación
FelipeAls
Usa el módulo body-parser . Estos son algunos ejemplos de uso útil para body-parser
drorw

Respuestas:

1251

Las cosas han cambiado una vez más a partir de Express 4.16.0 , ahora puede usar express.json()y express.urlencoded()al igual que en Express 3.0 .

Esto fue diferente a partir de Express 4.0 a 4.15 :

$ npm install --save body-parser

y entonces:

var bodyParser = require('body-parser')
app.use( bodyParser.json() );       // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({     // to support URL-encoded bodies
  extended: true
})); 

El resto es como en Express 3.0 :

En primer lugar, debe agregar algún middleware para analizar los datos de publicación del cuerpo.

Agregue una o ambas de las siguientes líneas de código:

app.use(express.json());       // to support JSON-encoded bodies
app.use(express.urlencoded()); // to support URL-encoded bodies

Luego, en su controlador, use el req.bodyobjeto:

// assuming POST: name=foo&color=red            <-- URL encoding
//
// or       POST: {"name":"foo","color":"red"}  <-- JSON encoding

app.post('/test-page', function(req, res) {
    var name = req.body.name,
        color = req.body.color;
    // ...
});

Tenga en cuenta que express.bodyParser()no se recomienda el uso de .

app.use(express.bodyParser());

...es equivalente a:

app.use(express.json());
app.use(express.urlencoded());
app.use(express.multipart());

Existen problemas de seguridad express.multipart(), por lo que es mejor agregar explícitamente soporte para los tipos de codificación específicos que necesita. Si necesita una codificación multiparte (por ejemplo, para admitir la carga de archivos), debería leer esto .

Drew Noakes
fuente
76
Si esta respuesta no funciona correctamente, asegúrese de tener el content-typeencabezado configurado, por ejemplo:curl -d '{"good_food":["pizza"]}' -H 'content-type:application/json' "http://www.example.com/your_endpoint"
SooDesuNe
66
¿Cuál es la diferencia entre publicar un formulario con pares de nombre / valor y publicar un cuerpo JSON? ¿Ambos aparecen en req.body?
chovy
77
@chovy Sí, lo hacen. bodyParserextrae datos JSON, codificados en URL y multiparte en el req.bodyobjeto.
Kristján
77
Este código me dio errores ya que el middleware ya no está incluido en Express; deberás usar body-parser: github.com/senchalabs/connect#middleware
araneae
11
Para leer json usando Express 4, solo la app.use(require('body-parser').json())línea es suficiente. Y luego puede leer los datos json del objeto del cuerpo de su solicitud, es decir req.body, desde una definición de ruta.
Martin Carel
90

Problema de seguridad con express.bodyParser ()

Mientras que todas las otras respuestas recomiendan actualmente utilizando el express.bodyParser()middleware, esto es en realidad una envoltura alrededor de la express.json(), express.urlencoded()y express.multipart()middleware ( http://expressjs.com/api.html#bodyParser ). El express.urlencoded()middleware realiza el análisis de los cuerpos de solicitud de formulario y es todo lo que necesita para exponer sus datos de formularioreq.body objeto.

Debido a una preocupación de seguridad sobre cómo express.multipart()/ connect.multipart()crea archivos temporales para todos los archivos cargados (y no se recolectan basura), ahora se recomienda no usar elexpress.bodyParser() contenedor sino usar solo los middlewares que necesita.

Nota: connect.bodyParser()pronto se actualizará para incluir solo urlencodedy jsoncuando se publique Connect 3.0 (que Express se extiende).


En resumen, en lugar de ...

app.use(express.bodyParser());

...Deberías usar

app.use(express.urlencoded());
app.use(express.json());      // if needed

y si necesita manejar formularios de varias partes (cargas de archivos), use una biblioteca de terceros o middleware como multiparte, busboy, dicer, etc.

Sean Lynch
fuente
Se agregó un comentario debajo de la pregunta para que más personas vean sus inquietudes y consejos. ¿Serían otras soluciones detalladas en la publicación del blog de Andrew Kelley (aún) relevantes en su opinión? (solo pregunto por otros, mis necesidades son puramente para herramientas internas ^^)
FelipeAls
@FelipeAls: Sí, y tenía la intención de hacer referencia a la publicación de Andrew también. Cualquiera de esas sugerencias (teniendo en cuenta las desventajas de cada una) son relevantes.
Sean Lynch el
Además, una vez que se lanza Connect 3.0 sin incluirlo multipart()como parte de él bodyParser(), bodyParser()vuelve a ser "seguro", pero deberá habilitar explícitamente el soporte multiparte utilizando una biblioteca de terceros.
Sean Lynch el
84

Nota : esta respuesta es para Express 2. Vea aquí para Express 3.

Si está utilizando connect / express, debe usar el middleware bodyParser : se describe en la guía Expressjs .

// example using express.js:
var express = require('express')
  , app = express.createServer();
app.use(express.bodyParser());
app.post('/', function(req, res){
  var email = req.param('email', null);  // second parameter is default
});

Aquí está la versión original de solo conexión:

// example using just connect
var connect = require('connect');
var url = require('url');
var qs = require('qs');
var server = connect(
  connect.bodyParser(),
  connect.router(function(app) {
    app.post('/userlogin', function(req, res) {
      // the bodyParser puts the parsed request in req.body.
      var parsedUrl = qs.parse(url.parse(req.url).query);
      var email = parsedUrl.email || req.body.email;;
    });
  })
);

Tanto la cadena de consulta como el cuerpo se analizan utilizando el manejo de parámetros de estilo Rails ( qs) en lugar de la biblioteca de bajo nivelquerystring . Con el fin de analizar los parámetros repetidos con qs, el parámetro debe tener paréntesis: name[]=val1&name[]=val2. También es compatible con mapas anidados. Además de analizar los envíos de formularios HTML, bodyParser puede analizar las solicitudes JSON automáticamente.

Editar : leí en express.js y modifiqué mi respuesta para que sea más natural para los usuarios de Express.

yonran
fuente
Mmm, ok. pruebo el bodyParser (). el documento dice que puedo obtenerlo de req.query () pero no obtuve nada. Eso es muy raro. No tengo ningún problema con Get tho.
murvinlai
3
No, req.query es SOLO los parámetros GET. Obtiene los datos POST a través de req.body. La función req.params () los incluye a ambos.
yonran
¡Un clic perdido rechazó esta respuesta accidentalmente sin que me diera cuenta! Ahora StackOverflow no me deja cambiarlo. Esp. frustrante ya que esto fue útil ... Voté por otra de sus buenas respuestas que no estaba buscando explícitamente para compensar. :)
HostileFork dice que no confíes en SE
33

Esto lo hará si desea crear la consulta publicada sin middleware:

app.post("/register/",function(req,res){
    var bodyStr = '';
    req.on("data",function(chunk){
        bodyStr += chunk.toString();
    });
    req.on("end",function(){
        res.send(bodyStr);
    });

});

Eso enviará esto al navegador

email=emailval&password1=pass1val&password2=pass2val

Sin embargo, probablemente sea mejor usar middleware para no tener que escribir esto una y otra vez en cada ruta.

med116
fuente
3
muuuy ... útil, para aquellos que no quieren confiar en una biblioteca que tarde o temprano quedará en desuso
Daniel
podrías construir fácilmente tu propio middleware
mayo
Esta es una gran respuesta, pero por qué hay texto adicional "---------------------------- 359856253150893337905494 Content-Disposition: form-data; name = "fullName" Ram ---------------------------- 359856253150893337905494-- "No quiero ese número.
Nawaraj
25

Nota para los usuarios de Express 4:

Si intenta app.use(express.bodyParser());ingresar a su aplicación, recibirá el siguiente error cuando intente iniciar su servidor Express:

Error: la mayoría del middleware (como bodyParser) ya no se incluye con Express y debe instalarse por separado. Consulte https://github.com/senchalabs/connect#middleware .

Tendrá que instalar el paquete por body-parserseparado de npm , luego usar algo como lo siguiente (ejemplo tomado de la página de GitHub ):

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

var app = express();

app.use(bodyParser());

app.use(function (req, res, next) {
  console.log(req.body) // populated!
  next();
})
mplewis
fuente
Muchas gracias por esta información. ¡Me estaba arrancando el pelo tratando de lidiar con la nueva forma de usar bodyParser! Este fue un gran avance - realmente lo aprecio
Tommy
1
heplp: body-parser obsoleto bodyParser: use json / middlewares codificados por urson individuales
Mohammad Faizan khan
19

Dada alguna forma:

<form action='/somepath' method='post'>
   <input type='text' name='name'></input>
</form>

Usando express

app.post('/somepath', function(req, res) {

    console.log(JSON.stringify(req.body));

    console.log('req.body.name', req.body['name']);
});

Salida:

{"name":"x","description":"x"}
req.param.name x
David
fuente
66
no funcionó para mí necesita usar app.use (express.bodyParser ());
cawecoy
@cawecoy tiene toda la razón aquí, pero express.bodyParser () no funciona tan bien para mí, en desuso
Mohammad Faizan khan
@MohammadFaizankhan fue un trabajo experimental, ya no uso express, no puedo ayudar ahora Busca en Google funciones similares a express.bodyParser (). ¡buena suerte!
cawecoy
16

Backend:

import express from 'express';
import bodyParser from 'body-parser';

const app = express();
app.use(bodyParser.json()); // add a middleware (so that express can parse request.body's json)

app.post('/api/courses', (request, response) => {
  response.json(request.body);
});

Interfaz:

fetch("/api/courses", {
  method: 'POST',
  body: JSON.stringify({ hi: 'hello' }), // convert Js object to a string
  headers: new Headers({ "Content-Type": "application/json" }) // add headers
});
Lakesare
fuente
15
app.use(express.bodyParser());

Luego, para app.postsolicitarlo, puede obtener valores de publicación a través de req.body.{post request variable}.

Chinthaka Senanayaka
fuente
su variable de solicitud de publicación aquí, ¿es esa la identificación del campo de entrada en cuestión o el formulario completo o qué?
Eogcloud
2
express.bodyParser () está en desuso. actualice su respuesta
Mohammad Faizan khan
15

Actualización para Express 4.4.1

El middleware de lo siguiente se elimina de Express.

  • bodyParser
  • json
  • codificado por urlen
  • multiparte

Cuando usa el middleware directamente como lo hizo en express 3.0. Recibirá el siguiente error:

Error: Most middleware (like urlencoded) is no longer bundled with Express and 
must be installed separately.


Para utilizar esos middleware, ahora necesita hacer npm para cada middleware por separado.

Como bodyParser está marcado como obsoleto, recomiendo la siguiente forma de usar json, urlencode y analizador multiparte como formidable, connect-multiparty. (El middleware multiparte también está en desuso).

También recuerde, solo definiendo urlencode + json, los datos del formulario no se analizarán y req.body estará indefinido. Debe definir un middleware para manejar la solicitud multiparte.

var urlencode = require('urlencode');
var json = require('json-middleware');
var multipart = require('connect-multiparty');
var multipartMiddleware = multipart();

app.use(json);
app.use(urlencode);
app.use('/url/that/accepts/form-data', multipartMiddleware);
yeelan
fuente
Supongo que esta es una actualización de características realmente mala
Mohammad Faizan khan
solo por el análisis del cuerpo tengo que hacer mucho código. qué es el hack
Mohammad Faizan khan
1
Tuve que agregar ".middleware ()" para requerir ('json-middleware') para que esto funcione.
DustinB
8

Para Express 4.1 y superior

Como la mayoría de las respuestas se utilizan para Express, bodyParser, connect; donde multiparte está en desuso. Hay una forma segura de enviar fácilmente objetos de varias partes posteriores.

Multer se puede usar como reemplazo de connect.multipart ().

Para instalar el paquete

$ npm install multer

Cárgalo en tu aplicación:

var multer = require('multer');

Y luego, agréguelo en la pila de middleware junto con el otro middleware de análisis de formularios.

app.use(express.json());
app.use(express.urlencoded());
app.use(multer({ dest: './uploads/' }));

connect.json () maneja la aplicación / json

connect.urlencoded () maneja la aplicación / x-www-form-urlencoded

multer () maneja datos multiparte / formulario

Lalit Umbarkar
fuente
8

Estaba buscando este problema exacto. Seguía todos los consejos anteriores, pero req.body aún devolvía un objeto vacío {}. En mi caso, era algo tan simple como que el html era incorrecto.

En el html de su formulario, asegúrese de usar el 'name'atributo en sus etiquetas de entrada, no solo 'id'. De lo contrario, no se analiza nada.

<input id='foo' type='text' value='1'/>             // req = {}
<input id='foo' type='text' name='foo' value='1' /> // req = {foo:1}

Mi error idiota es tu beneficio.

cwingrav
fuente
El mismo problema aqui. Pero estaba usando el atributo de nombre desde el principio. Veamos cuál es el problema.
Saif Al Falah
6

No deberías usar app.use (express.bodyParser ()) . BodyParser es una unión de json + urlencoded + mulitpart. No deberías usar esto porque la multiparte se eliminará en connect 3.0.

Para resolver eso, puedes hacer esto:

app.use(express.json());
app.use(express.urlencoded());

Es muy importante saber que app.use (app.router) debe usarse después de json y urlencoded, de lo contrario no funciona.

HenioJR
fuente
4

Solicitar streaming funcionó para mí

req.on('end', function() {
    var paramstring = postdata.split("&");
});

var postdata = "";
req.on('data', function(postdataChunk){
    postdata += postdataChunk;
});
zeah
fuente
1
Mejor que hacerlo postdata.split("&")sería cargar el módulo central querystring = require('querystring')y luego analizarlo postdatacon querystring.parse(postdata);
John Slegers
4

Podría encontrar todos los parámetros usando el siguiente código para las solicitudes POST y GET .

var express = require('express');
var app = express();
const util = require('util');
app.post('/', function (req, res) {
    console.log("Got a POST request for the homepage");
    res.send(util.inspect(req.query,false,null));
})
ARUNBALAN NV
fuente
¿te importaría actualizar la respuesta con tu versión de express?
lfender6445
3

Escrito en Express versión 4.16

Dentro de la función del enrutador puede usar la req.bodypropiedad para acceder a la variable de publicación. Por ejemplo, si esta fuera la POSTruta de su formulario, devolvería lo que ingresó:

function(req,res){
      res.send(req.body);

      //req.body.email would correspond with the HTML <input name="email"/>
}

PS para aquellos que están familiarizados con PHP: para acceder a la $_GETvariable de PHP que usamos req.queryy para acceder a la $_POSTvariable de PHP que usamos req.bodyen Node.js.

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

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

app.get('/',function(req,res){
  res.sendfile("index.html");
});
app.post('/login',function(req,res){
  var user_name=req.body.user;
  var password=req.body.password;
  console.log("User name = "+user_name+", password is "+password);
  res.end("yes");
});
app.listen(3000,function(){
  console.log("Started on PORT 3000");
})
seme
fuente
1

Los parámetros de publicación se pueden recuperar de la siguiente manera:

app.post('/api/v1/test',Testfunction);
http.createServer(app).listen(port, function(){
    console.log("Express server listening on port " + port)
});

function Testfunction(request,response,next) {
   console.log(request.param("val1"));
   response.send('HI');
}
HamidKhan
fuente
2
¿Te das cuenta de que esto no funcionará? paramse utiliza para solicitudes GET ... no POST y su ejemplo carece de detalles, muy confuso para los recién llegados. Y además de eso en request.paramrealidad está en desuso, por lo que su ejemplo es incorrecto en muchos niveles.
vdegenne
0

Está utilizando req.query.postun método incorrecto con el que req.query.postfunciona method=get, method=postfunciona con el analizador de cuerpo .

Simplemente intente esto cambiando la publicación para obtener :

<form id="loginformA" action="userlogin" method="get">
<div>
    <label for="email">Email: </label>
    <input type="text" id="email" name="email"></input>
</div>
<input type="submit" value="Submit"></input>  
</form>

Y en código expreso use 'app.get'

sagar saini
fuente
0

Utilice el paquete express-fileupload :

var app = require('express')();
var http = require('http').Server(app);
const fileUpload = require('express-fileupload')

app.use(fileUpload());

app.post('/', function(req, res) {
  var email = req.body.email;
  res.send('<h1>Email :</h1> '+email);
});

http.listen(3000, function(){
  console.log('Running Port:3000');
});
Chirag
fuente