Comment récupérer les paramètres de requête POST?

768

Voici ma forme 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>

Voici mon code Express.js /Node.js:

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

J'ai essayé sReq.query.emailou sReq.query['email']ou sReq.params['email'], etc. Aucun d'entre eux ne fonctionne. Ils reviennent tous undefined.

Lorsque je passe à un appel Get, cela fonctionne, alors .. une idée?

murvinlai
la source
33
SÉCURITÉ : tous ceux qui utilisent les bodyParser()réponses ici devraient également lire la réponse de
@SeanLynch
Utilisez le module body-parser . Voici quelques exemples d'utilisation utiles pour l'analyseur
corporel

Réponses:

1251

Les choses ont changé une fois de plus à partir d' Express 4.16.0 , vous pouvez maintenant utiliser express.json()et express.urlencoded()tout comme dans Express 3.0 .

C'était différent à partir d' Express 4.0 à 4.15 :

$ npm install --save body-parser

et alors:

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

Le reste est comme dans Express 3.0 :

Tout d'abord, vous devez ajouter un middleware pour analyser les données de publication du corps.

Ajoutez une ou les deux lignes de code suivantes:

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

Ensuite, dans votre gestionnaire, utilisez l' req.bodyobjet:

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

Notez que l'utilisation de express.bodyParser()n'est pas recommandée.

app.use(express.bodyParser());

...est équivalent à:

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

Des problèmes de sécurité existent avec express.multipart(), et il est donc préférable d'ajouter explicitement la prise en charge du ou des types d'encodage spécifiques dont vous avez besoin. Si vous avez besoin d'un codage en plusieurs parties (pour prendre en charge le téléchargement de fichiers par exemple), vous devez lire ceci .

Drew Noakes
la source
76
Si cette réponse ne fonctionne pas correctement, assurez-vous que l'en- content-typetête est défini, par exemple:curl -d '{"good_food":["pizza"]}' -H 'content-type:application/json' "http://www.example.com/your_endpoint"
SooDesuNe
6
Quelle est la différence entre publier un formulaire avec des paires nom / valeur et publier un corps JSON? Est-ce qu'ils apparaissent tous les deux dans le corps du candidat?
chovy
7
@chovy Oui, ils le font. bodyParserrésume les données JSON, codées URL et multiparties dans l' req.bodyobjet.
Kristján
7
Ce code m'a donné des erreurs car le middleware n'est plus fourni avec Express; vous devrez utiliser l'analyseur de corps: github.com/senchalabs/connect#middleware
araneae
11
Pour lire json en utilisant Express 4, seule la app.use(require('body-parser').json())ligne est suffisante. Et puis, vous pouvez lire les données json de l'objet corps de votre demande, c'est req.body-à- dire à partir d'une définition d'itinéraire.
Martin Carel
90

Problème de sécurité avec express.bodyParser ()

Alors que toutes les autres réponses recommandent actuellement l' utilisation du express.bodyParser()middleware, c'est en fait une enveloppe autour de la express.json(), express.urlencoded()et express.multipart()intergiciels ( http://expressjs.com/api.html#bodyParser ). L'analyse des corps de demande de formulaire est effectuée par le express.urlencoded()middleware et est tout ce dont vous avez besoin pour exposer vos données de formulaire sur l' req.bodyobjet.

En raison d'un problème de sécurité concernant la façon dont express.multipart()/ connect.multipart()crée des fichiers temporaires pour tous les fichiers téléchargés (et ne sont pas récupérés), il est maintenant recommandé de ne pas utiliser le express.bodyParser()wrapper mais d'utiliser uniquement les middlewares dont vous avez besoin.

Remarque: connect.bodyParser()sera bientôt mis à jour pour inclure uniquement urlencodedet jsonlorsque Connect 3.0 sera publié (qu'Express étend).


Donc en bref, au lieu de ...

app.use(express.bodyParser());

...Tu devrais utiliser

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

et si / quand vous avez besoin de gérer des formulaires en plusieurs parties (téléchargements de fichiers), utilisez une bibliothèque ou un middleware tiers tel que multipartie, busboy, dicer, etc.

Sean Lynch
la source
Ajout d'un commentaire sous la question afin que plus de gens voient vos préoccupations et vos conseils. D'autres solutions détaillées dans le blog d'Andrew Kelley seraient-elles (encore) pertinentes à votre avis? (juste pour demander aux autres, mes besoins sont purement pour des outils internes ^^)
FelipeAls
@FelipeAls - Oui, et je voulais également faire référence au post d'Andrew. Chacune de ces suggestions (en tenant compte des chutes de chacune) est pertinente.
Sean Lynch
De plus, une fois que Connect 3.0 est sorti sans être inclus multipart()dans bodyParser(), il bodyParser()redevient "sûr", mais vous devrez activer explicitement la prise en charge de plusieurs parties à l'aide d'une bibliothèque tierce.
Sean Lynch
84

Remarque : cette réponse est pour Express 2. Voir ici pour Express 3.

Si vous utilisez connect / express, vous devez utiliser le middleware bodyParser : il est décrit dans le guide 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
});

Voici la version originale connectée uniquement:

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

La chaîne de requête et le corps sont analysés à l'aide de la gestion des paramètres de style Rails ( qs) plutôt que de la bibliothèque de bas niveauquerystring . Afin d'analyser les paramètres répétés avec qs, le paramètre doit être muni de supports: name[]=val1&name[]=val2. Il prend également en charge les cartes imbriquées. En plus d'analyser les soumissions de formulaires HTML, bodyParser peut analyser automatiquement les demandes JSON.

Edit : J'ai lu sur express.js et modifié ma réponse pour être plus naturel pour les utilisateurs d'Express.

yonran
la source
Hmm ok. j'essaye le bodyParser (). le doc dit que je peux l'obtenir de req.query () mais je n'ai rien. c'est très bizarre. Je n'ai aucun problème avec Get tho.
murvinlai
3
Non, la requête de requête est UNIQUEMENT les paramètres GET. Vous obtenez les données POST via req.body. La fonction req.params () inclut les deux.
yonran
Un clic errant a fait voter cette réponse accidentellement sans que je m'en rende compte! Maintenant, StackOverflow ne me laisse pas le changer. Esp. frustrant car cela a été utile ... J'ai voté une autre de vos bonnes réponses que je ne cherchais pas explicitement à compenser. :)
HostileFork dit de ne pas faire confiance au SE
33

Cela le fera si vous souhaitez créer la requête publiée sans middleware:

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

});

Cela enverra cela au navigateur

email=emailval&password1=pass1val&password2=pass2val

Il est probablement préférable d'utiliser un middleware afin de ne pas avoir à l'écrire encore et encore dans chaque itinéraire.

med116
la source
3
sooo .... pratique, pour ceux qui ne veulent pas compter sur une bibliothèque qui sera tôt ou tard dépréciée
Daniel
vous pouvez facilement créer votre propre middleware
maioman
C'est une excellente réponse mais pourquoi il y a du texte supplémentaire "---------------------------- 359856253150893337905494 Content-Disposition: form-data; name = "fullName" Ram ---------------------------- 359856253150893337905494-- "Je ne veux pas de ce numéro.
Nawaraj
25

Remarque pour les utilisateurs d'Express 4:

Si vous essayez de mettre app.use(express.bodyParser());dans votre application, vous obtiendrez l'erreur suivante lorsque vous essayez de démarrer votre serveur Express:

Erreur: la plupart des middlewares (comme bodyParser) ne sont plus fournis avec Express et doivent être installés séparément. Veuillez consulter https://github.com/senchalabs/connect#middleware .

Vous devrez installer le package body-parserséparément de npm , puis utiliser quelque chose comme ceci (exemple tiré de la page 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
la source
Merci beaucoup pour ces informations. J'arrachais mes cheveux en essayant de faire face à la nouvelle façon d'utiliser bodyParser! Ce fut une grande percée - vraiment apprécier
Tommy
1
heplp: body-parser body obsolète Parser: utiliser des middlewares json / urlencoded individuels
Mohammad Faizan khan
19

Étant donné une certaine forme:

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

Utilisation express

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

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

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

Production:

{"name":"x","description":"x"}
req.param.name x
David
la source
6
n'a pas fonctionné pour moi. besoin d'utiliser app.use (express.bodyParser ());
cawecoy
@cawecoy est absolument le même ici mais express.bodyParser () ne fonctionne pas aussi bien pour moi, il est obsolète
Mohammad Faizan khan
@MohammadFaizankhan c'était un travail expérimental, je n'utilisais plus express, je ne peux pas aider maintenant. Google pour des fonctions similaires à express.bodyParser (). bonne chance!
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);
});

L'extrémité avant:

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

Ensuite, pour la app.postdemande, vous pouvez obtenir des valeurs de publication via req.body.{post request variable}.

Chinthaka Senanayaka
la source
votre variable de demande de publication ici, est-ce l'ID du champ de saisie en question ou le formulaire entier ou quoi?
Eogcloud
2
express.bodyParser () est obsolète. mettez à jour votre réponse
Mohammad Faizan khan
15

Mise à jour pour Express 4.4.1

Le middleware des éléments suivants est supprimé d'Express.

  • bodyParser
  • json
  • urlencoded
  • multipart

Lorsque vous utilisez le middleware directement comme vous l'avez fait dans express 3.0. Vous obtiendrez l'erreur suivante:

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


Afin d'utiliser ces middlewares, vous devez maintenant faire npm pour chaque middleware séparément.

Étant donné que bodyParser est marqué comme obsolète, je recommande donc la façon suivante d'utiliser json, urlencode et analyseur multipartie comme formidable, connect-multiparty. (Le middleware multipartie est également obsolète).

Souvenez-vous également qu'en définissant simplement urlencode + json, les données du formulaire ne seront pas analysées et req.body ne sera pas défini. Vous devez définir un middleware pour gérer la demande en plusieurs parties.

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
la source
je suppose que c'est vraiment une mauvaise mise à jour des fonctionnalités
Mohammad Faizan khan
juste pour des raisons d'analyse corporelle, je dois faire beaucoup de code. ce que le hack est
Mohammad Faizan khan
1
J'ai dû ajouter ".middleware ()" pour exiger ('json-middleware') pour que cela fonctionne.
DustinB
8

Pour Express 4.1 et supérieur

Comme la plupart des réponses utilisent Express, bodyParser, connect; où multipart est déconseillé. Il existe un moyen sécurisé d'envoyer facilement des objets post-multiparties.

Multer peut être utilisé en remplacement de connect.multipart ().

Pour installer le package

$ npm install multer

Chargez-le dans votre application:

var multer = require('multer');

Et puis, ajoutez-le dans la pile du middleware avec l'autre middleware d'analyse de formulaire.

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

connect.json () gère l'application / json

connect.urlencoded () gère l'application / x-www-form-urlencoded

multer () gère les données multipart / form-data

Lalit Umbarkar
la source
8

Je cherchais ce problème exact. Je suivais tous les conseils ci-dessus mais req.body renvoyait toujours un objet vide {}. Dans mon cas, c'était quelque chose d'aussi simple que le html étant incorrect.

Dans le html de votre formulaire, assurez-vous d'utiliser l' 'name'attribut dans vos balises d'entrée, pas seulement 'id'. Sinon, rien n'est analysé.

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

Mon erreur idiote est votre avantage.

cwingrav
la source
Même problème ici. Mais j'utilisais l'attribut name depuis le début. Voyons quel est le problème.
Saif Al Falah
6

Vous ne devez pas utiliser app.use (express.bodyParser ()) . BodyParser est une union de json + urlencoded + mulitpart. Vous ne devriez pas utiliser ceci car le multipart sera supprimé dans connect 3.0.

Pour résoudre cela, vous pouvez procéder comme suit:

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

Il est très important de savoir que app.use (app.router) doit être utilisé après json et urlencodé, sinon cela ne fonctionne pas!

HenioJR
la source
4

La demande de streaming a fonctionné pour moi

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

var postdata = "";
req.on('data', function(postdataChunk){
    postdata += postdataChunk;
});
ouais
la source
1
Mieux que de faire postdata.split("&")serait de charger le module de base querystring = require('querystring')puis d'analyser votre postdataavec querystring.parse(postdata);
John Slegers
4

J'ai pu trouver tous les paramètres en utilisant le code suivant pour les requêtes POST et 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
la source
cela vous dérange-t-il de mettre à jour la réponse avec votre version d'express?
lfender6445
3

Écrit à Express version 4.16

À l'intérieur de la fonction de routeur, vous pouvez utiliser la req.bodypropriété pour accéder à la variable de publication. Par exemple, s'il s'agissait de l' POSTitinéraire de votre formulaire, il renverrait ce que vous avez entré:

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

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

PS pour ceux qui connaissent PHP: Afin d'accéder à la $_GETvariable PHP que nous utilisons req.queryet d'accéder à la $_POSTvariable PHP que nous utilisons req.bodydans Node.js.

Logan
la source
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
la source
1

Les paramètres de publication peuvent être récupérés comme suit:

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
la source
2
vous rendez-vous compte que cela ne fonctionnera pas? paramest utilisé pour les requêtes GET .. pas POST et votre exemple manque de détails, très déroutant pour les nouveaux arrivants. Et en plus de cela request.paramest en fait obsolète, donc votre exemple est erroné à tant de niveaux.
vdegenne
0

Vous utilisez req.query.postavec une mauvaise méthode req.query.postfonctionne avec method=get, method=postfonctionne avec body-parser .

Essayez simplement cela en changeant de poste pour obtenir :

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

Et dans le code express, utilisez 'app.get'

sagar saini
la source
0

Utilisez le package 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
la source