Como recuperar parâmetros de consulta POST?

768

Aqui está o meu formulário simples:

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

Aqui está o meu código Express.js /Node.js:

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

Eu tentei sReq.query.emailou sReq.query['email']ou sReq.params['email'], etc. Nenhum deles funciona. Todos eles retornam undefined.

Quando mudo para uma chamada Get, funciona, então ... alguma ideia?

murvinlai
fonte
33
SEGURANÇA : todos os que usam as bodyParser()respostas aqui também devem ler a resposta de
@SeanLynch
Use o módulo analisador de corpo . Aqui estão alguns exemplos de uso usful para o corpo-parser
drorw

Respostas:

1251

As coisas mudaram mais uma vez a partir do Express 4.16.0 , agora você pode usar express.json()e, express.urlencoded()assim como no Express 3.0 .

Isso foi diferente ao iniciar o Express 4.0 a 4.15 :

$ npm install --save body-parser

e depois:

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

O resto é como no Express 3.0 :

Primeiro, você precisa adicionar algum middleware para analisar os dados de postagem do corpo.

Adicione uma ou ambas as seguintes linhas de código:

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

Em seguida, no seu manipulador, use o 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;
    // ...
});

Observe que o uso de express.bodyParser()não é recomendado.

app.use(express.bodyParser());

...é equivalente a:

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

Existem preocupações de segurança express.multipart()e, portanto, é melhor adicionar explicitamente suporte para os tipos de codificação específicos necessários. Se você precisar de codificação multiparte (para suportar o upload de arquivos, por exemplo), leia isso .

Drew Noakes
fonte
76
Se esta resposta não estiver funcionando corretamente, verifique se o content-typecabeçalho está definido, por exemplo:curl -d '{"good_food":["pizza"]}' -H 'content-type:application/json' "http://www.example.com/your_endpoint"
SooDesuNe
6
qual é a diferença entre postar um formulário com pares nome / valor e postar um corpo JSON? Os dois aparecem no req.body?
chovy 23/09/12
7
@ chovy Sim, eles fazem. bodyParserabstrai JSON, dados codificados por URL e multipartes no req.bodyobjeto.
Kristján
7
Esse código me deu erros, pois o middleware não está mais incluído no Express; você precisará usar o analisador de corpo: github.com/senchalabs/connect#middleware
araneae
11
Para ler json usando o Express 4, apenas a app.use(require('body-parser').json())linha é suficiente. E então você pode ler os dados json do objeto body da sua solicitação, ou seja req.body, de dentro de uma definição de rota.
Martin Carel
90

Preocupação de segurança usando express.bodyParser ()

Enquanto todas as outras respostas recomendar atualmente usando o express.bodyParser()middleware, este é realmente um invólucro em torno do express.json(), express.urlencoded()e express.multipart()middlewares ( http://expressjs.com/api.html#bodyParser ). A análise dos corpos de solicitação de formulário é feita pelo express.urlencoded()middleware e é tudo o que você precisa para expor seus dados de formulário no req.bodyobjeto.

Devido a uma preocupação de segurança sobre como express.multipart()/ connect.multipart()cria arquivos temporários para todos os arquivos carregados (e não são coletados de lixo), agora é recomendável não usar o express.bodyParser()wrapper, mas usar apenas os middlewares necessários.

Nota: connect.bodyParser()em breve será atualizado para incluir apenas urlencodede jsonquando o Connect 3.0 for lançado (que o Express estende).


Então, resumindo, em vez de ...

app.use(express.bodyParser());

...você deveria usar

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

e se / quando você precisar manipular formulários multipartes (upload de arquivos), use uma biblioteca ou middleware de terceiros, como multiparty, busboy, dicer, etc.

Sean Lynch
fonte
Foi adicionado um comentário abaixo da pergunta para que mais pessoas vejam suas preocupações e conselhos. Outras soluções detalhadas na postagem do blog de Andrew Kelley (ainda) são relevantes na sua opinião? (basta perguntar para os outros, as minhas necessidades são puramente para obter ferramentas internas ^^)
FelipeAls
@FelipeAls - Sim, e eu pretendia fazer referência também ao post de Andrew. Qualquer uma dessas sugestões (levando em consideração as quedas de cada uma) é relevante.
Sean Lynch
Além disso, quando o Connect 3.0 é lançado sem incluir multipart()como parte bodyParser(), bodyParser()torna-se "seguro" novamente, mas você precisará ativar explicitamente o suporte a várias partes usando uma biblioteca de terceiros.
Sean Lynch
84

Nota : esta resposta é para o Express 2. Consulte aqui para o Express 3.

Se você estiver usando o connect / express, deverá usar o middleware bodyParser : está descrito no guia 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
});

Aqui está a versão original somente para conexão:

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

A querystring e o body são analisados ​​usando manipulação de parâmetro no estilo Rails ( qs) em vez da biblioteca de baixo nívelquerystring . A fim de analisar parâmetros repetidos com qs, o parâmetro precisa ter parênteses: name[]=val1&name[]=val2. Ele também suporta mapas aninhados. Além de analisar envios de formulários HTML, o bodyParser pode analisar solicitações JSON automaticamente.

Editar : li o express.js e modifiquei minha resposta para ser mais natural para os usuários do Express.

yonran
fonte
Hmm ok. Eu tento o bodyParser (). o documento diz que posso obtê-lo em req.query (), mas não obtive nada. isso é muito estranho. Não tenho nenhum problema com Get tho.
murvinlai
3
Não, req.query é APENAS os parâmetros GET. Você obtém os dados do POST através do req.body. A função req.params () inclui os dois.
yonran
Um clique perdido desrespeitou esta resposta acidentalmente sem que eu percebesse! Agora o StackOverflow não me permite alterá-lo. Esp. frustrante, pois isso foi útil ... votei mais uma de suas boas respostas que não estava procurando explicitamente. :)
HostileFork disse que não confia em SE 11/04/12
33

Isso será feito se você deseja criar a consulta publicada sem o middleware:

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

});

Isso enviará isso para o navegador

email=emailval&password1=pass1val&password2=pass2val

Provavelmente é melhor usar o middleware para que você não precise escrever isso repetidamente em cada rota.

med116
fonte
3
sooo .... acessível, para aqueles que não quer contar com uma biblioteca que, mais cedo ou mais tarde, ser preterido
Daniel
você pode facilmente criar seu próprio middleware
maioman
Esta é uma ótima resposta, mas por que há texto extra "---------------------------- 359856253150893337905494 Disposição de conteúdo: formulário-dados; nome = "fullName" Ram ---------------------------- 359856253150893337905494-- "Eu não quero esse número.
Nawaraj
25

Nota para usuários do Express 4:

Se você tentar entrar app.use(express.bodyParser());no seu aplicativo, receberá o seguinte erro ao tentar iniciar o servidor Express:

Erro: a maioria dos middlewares (como bodyParser) não é mais empacotada com o Express e deve ser instalada separadamente. Consulte https://github.com/senchalabs/connect#middleware .

Você precisará instalar o pacote body-parserseparadamente do npm e , em seguida, usar algo como o seguinte (exemplo da página do 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
fonte
Muito obrigado por esta informação. Estava puxando meu cabelo tentando lidar com a nova maneira de usar bodyParser! Esta foi uma grande inovação - realmente aprecio #
Tommy
1
heplp: corpo-parser obsoleto bodyParser: uso individuais JSON / middlewares urlencoded
Mohammad Faizan khan
19

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

Resultado:

{"name":"x","description":"x"}
req.param.name x
David
fonte
6
não funcionou para mim. precisa usar app.use (express.bodyParser ());
cawecoy
@cawecoy absolutamente certo mesmo aqui, mas express.bodyParser () não está funcionando bem para mim é obsoleta
Mohammad Faizan khan
@MohammadFaizankhan, foi um trabalho experimental, não usei mais o Express, não posso ajudar agora. Pesquise no Google por funções semelhantes a express.bodyParser (). boa sorte!
cawecoy
16

Processo interno:

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

A parte dianteira:

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
fonte
15
app.use(express.bodyParser());

Em seguida, para app.postsolicitação, você pode obter valores de postagem via req.body.{post request variable}.

Chinthaka Senanayaka
fonte
sua variável de solicitação de postagem aqui, é esse o ID do campo de entrada em questão ou o formulário inteiro ou o quê?
Eogcloud
2
express.bodyParser () foi descontinuado. atualize sua resposta
Mohammad Faizan khan
15

Atualização para o Express 4.4.1

O middleware a seguir é removido do Express.

  • bodyParser
  • json
  • codificado por url
  • multipart

Quando você usa o middleware diretamente, como no express 3.0. Você receberá o seguinte erro:

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


Para utilizar esses middlewares, agora você precisa executar o npm para cada middleware separadamente.

Como bodyParser está marcado como obsoleto, recomendo a seguinte maneira usando json, urlencode e analisador de várias partes, como formidável, connect-multiparty. (O middleware de várias partes também está obsoleto).

Lembre-se também, apenas definindo urlencode + json, os dados do formulário não serão analisados ​​e req.body será indefinido. Você precisa definir um middleware para lidar com a solicitação de várias partes.

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
fonte
Eu acho que isso é muito ruim updation recurso
Mohammad Faizan khan
apenas por uma questão de análise do corpo, eu tenho que fazer muito código. qual é o truque #
Mohammad Faizan khan
1
Eu tive que adicionar ".middleware ()" para exigir ('json-middleware') para que isso funcionasse.
DustinB 26/11
8

Para o Express 4.1 e superior

Como a maioria das respostas está usando o Express, bodyParser, connect; onde multipart está obsoleto. Existe uma maneira segura de enviar objetos multipartes com facilidade.

Multer pode ser usado como substituto de connect.multipart ().

Para instalar o pacote

$ npm install multer

Carregue-o no seu aplicativo:

var multer = require('multer');

Em seguida, adicione-o na pilha de middleware junto com o outro formulário que analisa o middleware.

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

connect.json () manipula application / json

connect.urlencoded () manipula application / x-www-form-urlencoded

multer () lida com dados de várias partes / formulário

Lalit Umbarkar
fonte
8

Eu estava procurando por esse problema exato. Eu estava seguindo todos os conselhos acima, mas req.body ainda estava retornando um objeto vazio {}. No meu caso, era algo tão simples quanto o html estar incorreto.

No html do seu formulário, use o 'name'atributo em suas tags de entrada, não apenas 'id'. Caso contrário, nada será analisado.

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

Meu erro idiota é o seu benefício.

cwingrav
fonte
Mesmo problema aqui. Mas eu estava usando o atributo name desde o início. Vamos ver qual é o problema.
Saif Al Falah
6

Você não deve usar app.use (express.bodyParser ()) . BodyParser é uma união de json + urlencoded + mulitpart. Você não deve usar isso porque o multipart será removido no connect 3.0.

Para resolver isso, você pode fazer o seguinte:

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

É muito importante saber que o app.use (app.router) deve ser usado após o json e o código da URL , caso contrário não funciona!

HenioJR
fonte
4

O fluxo de pedidos funcionou para mim

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

var postdata = "";
req.on('data', function(postdataChunk){
    postdata += postdataChunk;
});
zeah
fonte
1
Melhor do que fazer postdata.split("&")seria carregar módulo central querystring = require('querystring')e, em seguida, analisar o seu postdatacom querystring.parse(postdata);
John Slegers
4

Eu pude encontrar todos os parâmetros usando o código a seguir para solicitações POST e 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
fonte
você se importa de atualizar a resposta com sua versão do express?
precisa saber é o seguinte
3

Escrito na versão Express 4.16

Dentro da função do roteador, você pode usar a req.bodypropriedade para acessar a variável post. Por exemplo, se esse era o POSTcaminho do seu formulário, ele enviaria de volta o que você inseriu:

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

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

PS para aqueles que estão familiarizados com o PHP: Para acessar a $_GETvariável do PHP , usamos req.querye para acessar a $_POSTvariável do PHP , usamos req.bodyno Node.js.

Logan
fonte
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
fonte
1

Os parâmetros de postagem podem ser recuperados da seguinte maneira:

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
fonte
2
você percebe que isso não vai funcionar? paramé usado para solicitações GET .. não POST e seu exemplo carece de detalhes, muito confuso para os novatos. Além disso, ele request.paramestá realmente obsoleto, então seu exemplo está errado em muitos níveis.
Vdegenne 14/0418
0

Você está usando o req.query.postmétodo errado, req.query.posttrabalha com method=get, method=posttrabalha com o analisador de corpo .

Apenas tente isso alterando a postagem para obter :

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

E no código expresso, use 'app.get'

sagar saini
fonte
0

Use o pacote 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
fonte