Come recuperare i parametri della query POST?


768

Ecco la mia forma semplice:

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

Ecco il mio codice Express.js /Node.js:

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

Ho provato sReq.query.emailo sReq.query['email']o sReq.params['email'], ecc. Nessuno di loro funziona. Tutti ritornano undefined.

Quando cambio a una chiamata, funziona, quindi ... qualche idea?


33
SICUREZZA : tutti quelli che usano le bodyParser()risposte qui dovrebbero anche leggere la risposta di
@SeanLynch in

Utilizzare il modulo body-parser . Ecco alcuni esempi di utilizzo utili per body-parser
drorw,

Risposte:


1251

Le cose sono cambiate ancora una volta a partire da Express 4.16.0 , ora puoi usare express.json()e express.urlencoded()proprio come in Express 3.0 .

È stato diverso a partire da Express 4.0 a 4.15 :

$ npm install --save body-parser

e poi:

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

Il resto è come in Express 3.0 :

Innanzitutto è necessario aggiungere un middleware per analizzare i dati di post del corpo.

Aggiungi una o entrambe le seguenti righe di codice:

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

Quindi, nel gestore, utilizzare l' req.bodyoggetto:

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

Si noti che l'uso di express.bodyParser()non è raccomandato.

app.use(express.bodyParser());

...è equivalente a:

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

Esistono problemi di sicurezza express.multipart(), quindi è meglio aggiungere esplicitamente il supporto per i tipi di codifica specifici richiesti. Se hai bisogno della codifica multipart (ad esempio per supportare il caricamento di file), dovresti leggere questo .


76
Se questa risposta non funziona correttamente, assicurati di avere l' content-typeintestazione impostata, ad esempio:curl -d '{"good_food":["pizza"]}' -H 'content-type:application/json' "http://www.example.com/your_endpoint"
SooDesuNe

6
qual è la differenza tra la pubblicazione di un modulo con coppie nome / valore e la pubblicazione di un corpo JSON? Si presentano entrambi in req.body?
Chovy

7
@chovy Sì, lo fanno. bodyParserestrae i dati JSON, codificati in URL e multipart req.bodynell'oggetto.
Kristján,

7
Questo codice mi ha dato errori poiché il middleware non è più associato a Express; dovrai usare body-parser: github.com/senchalabs/connect#middleware
araneae

11
Per leggere json usando Express 4, app.use(require('body-parser').json())è sufficiente solo la riga. E poi puoi leggere i dati json dall'oggetto body della tua richiesta, cioè req.bodydall'interno di una definizione di route.
Martin Carel,

90

Problemi di sicurezza con express.bodyParser ()

Mentre tutte le altre risposte attualmente consiglia di utilizzare il express.bodyParser()middleware, questo è in realtà un wrapper express.json(), express.urlencoded()e express.multipart()middleware ( http://expressjs.com/api.html#bodyParser ). L'analisi dei corpi di richiesta del modulo viene eseguita dal express.urlencoded()middleware ed è tutto ciò che serve per esporre i dati del modulo req.bodysull'oggetto.

A causa di un problema di sicurezza relativo a come express.multipart()/ connect.multipart()crea file temporanei per tutti i file caricati (e non vengono raccolti in modo inutile), ora si consiglia di non utilizzare il express.bodyParser()wrapper ma di utilizzare solo i middleware necessari.

Nota: connect.bodyParser()verrà presto aggiornato per includere solo urlencodede jsonquando verrà rilasciato Connect 3.0 (che Express estende).


Quindi in breve, invece di ...

app.use(express.bodyParser());

...dovresti usare

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

e se / quando è necessario gestire moduli multipart (upload di file), utilizzare una libreria o un middleware di terze parti come multiparty, busboy, dicer, ecc.


Aggiunto un commento sotto la domanda in modo che più persone vedano le tue preoccupazioni e i tuoi consigli. Altre soluzioni dettagliate nel post del blog di Andrew Kelley (ancora) rilevanti secondo te? (solo chiedendo altri, i miei bisogni sono puramente strumenti interni ^^)
FelipeAls

@FelipeAls - Sì, e intendevo fare riferimento anche al post di Andrew. Ciascuno di questi suggerimenti (tenendo conto delle cadute di ciascuno) è rilevante.
Sean Lynch,

Inoltre, una volta che Connect 3.0 viene rilasciato senza includere multipart()come parte di bodyParser(), bodyParser()diventa di nuovo "sicuro", ma sarà necessario abilitare esplicitamente il supporto multipart utilizzando una libreria di terze parti.
Sean Lynch,

84

Nota : questa risposta è per Express 2. Vedi qui per Express 3.

Se stai usando connect / express, dovresti usare il middleware bodyParser : è descritto nella guida di 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
});

Ecco la versione originale di sola connessione:

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

Sia la querystring che il body vengono analizzati utilizzando la gestione dei parametri in stile Rails ( qs) anziché la libreria di basso livelloquerystring . Al fine di analizzare i parametri ripetuti con qs, il parametro deve avere staffe: name[]=val1&name[]=val2. Supporta anche mappe nidificate. Oltre all'analisi degli invii di moduli HTML, bodyParser può analizzare automaticamente le richieste JSON.

Modifica : ho letto su express.js e modificato la mia risposta per essere più naturale per gli utenti di Express.


Hmm va bene. provo il bodyParser (). il documento dice che posso ottenerlo da req.query () ma non ho ottenuto nulla. è molto strano. Non ho problemi con Get tho.
Murvinlai,

3
No, req.query è SOLO i parametri GET. Ottieni i dati POST tramite req.body. La funzione req.params () li include entrambi.
yonran,

Un clic randagio ha annullato accidentalmente questa risposta senza che me ne accorgessi! Ora StackOverflow non mi permette di cambiarlo. Esp. frustrante in quanto mi è stato utile ... Ho votato un'altra delle tue buone risposte che non stavo cercando esplicitamente di rimediare. :)
HostileFork afferma di non fidarsi

33

Questo lo farà se si desidera creare la query pubblicata senza middleware:

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

});

Questo invierà questo al browser

email=emailval&password1=pass1val&password2=pass2val

Probabilmente è meglio usare il middleware, quindi non è necessario scriverlo più e più volte in ogni percorso.


3
così ... utile, per coloro che non vogliono fare affidamento su una libreria che prima o poi sarà deprecata
Daniel,

potresti facilmente creare il tuo middleware
maioman,

Questa è un'ottima risposta ma perché c'è del testo in più "---------------------------- 359856253150893337905494 Disposizione-contenuto: form-data; nome = "fullName" Ram ---------------------------- 359856253150893337905494-- "Non voglio quel numero.
Nawaraj,

25

Nota per gli utenti di Express 4:

Se si tenta di inserire app.use(express.bodyParser());l'app, si verificherà il seguente errore quando si tenta di avviare il server Express:

Errore: la maggior parte dei middleware (come bodyParser) non è più inclusa in Express e deve essere installata separatamente. Si prega di consultare https://github.com/senchalabs/connect#middleware .

Dovrai installare il pacchetto body-parserseparatamente da npm , quindi utilizzare qualcosa di simile al seguente (esempio preso dalla pagina 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();
})

Grazie mille per queste informazioni. Mi stavo strappando i capelli cercando di affrontare il nuovo modo di usare bodyParser! Questa è stata una grande svolta - apprezzo molto
Tommy

1
heplp: body-parser deprecated bodyParser: usa singoli json / middleware urlencoded
Mohammad Faizan khan,

19

Dato un modulo:

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

Produzione:

{"name":"x","description":"x"}
req.param.name x

6
non ha funzionato per me. è necessario utilizzare app.use (express.bodyParser ());
cawecoy,

@cawecoy è esattamente lo stesso qui ma express.bodyParser () non funziona altrettanto bene per me è deprecato
Mohammad Faizan khan,

@MohammadFaizankhan è stato un lavoro sperimentale, non ho più usato express, non posso fare a meno. Google per funzioni simili a express.bodyParser (). buona fortuna!
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);
});

Fine frontale:

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

15
app.use(express.bodyParser());

Quindi per la app.postrichiesta è possibile ottenere i valori dei post tramite req.body.{post request variable}.


la tua variabile di richiesta di post qui, è l'id del campo di input in questione o l'intero modulo o cosa?
Eogcloud,

2
express.bodyParser () è deprecato. aggiorna la tua risposta
Mohammad Faizan khan,

15

Aggiornamento per Express 4.4.1

Il middleware di quanto segue viene rimosso da Express.

  • bodyParser
  • jSON
  • urlencoded
  • multipart

Quando si utilizza il middleware direttamente come in Express 3.0. Verrà visualizzato il seguente errore:

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


Per utilizzare questi middleware, ora devi fare npm per ciascun middleware separatamente.

Poiché bodyParser è contrassegnato come obsoleto, quindi ti consiglio di utilizzare Json, urlencode e il parser multipart come formidabile, connect-multiparty. (Anche il middleware multipart è obsoleto).

Ricorda anche che, semplicemente definendo urlencode + json, i dati del modulo non verranno analizzati e req.body non sarà definito. È necessario definire un middleware per gestire la richiesta multipart.

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

Immagino che questo sia davvero un brutto aggiornamento delle funzionalità
Mohammad Faizan khan,

solo per ragioni di body body devo fare un sacco di codice. cos'è l'hack
Mohammad Faizan khan,

1
Ho dovuto aggiungere ".middleware ()" per richiedere ('json-middleware') per farlo funzionare.
DustinB,

8

Per Express 4.1 e versioni successive

Poiché la maggior parte delle risposte utilizza Express, bodyParser, connect; dove multipart è deprecato. C'è un modo sicuro per inviare facilmente oggetti multipart post.

Il multer può essere usato in sostituzione di connect.multipart ().

Per installare il pacchetto

$ npm install multer

Caricalo nella tua app:

var multer = require('multer');

Quindi, aggiungilo nello stack del middleware insieme all'altro middleware di analisi del modulo.

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

connect.json () gestisce application / json

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

multer () gestisce multipart / form-data


8

Stavo cercando questo esatto problema. Stavo seguendo tutti i consigli sopra ma req.body stava ancora restituendo un oggetto vuoto {}. Nel mio caso, era qualcosa di semplice come l'html che non era corretto.

Nell'html del modulo, assicurati di utilizzare l' 'name'attributo nei tag di input, non solo 'id'. Altrimenti, nulla viene analizzato.

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

Il mio errore idiota è il tuo vantaggio.


Lo stesso problema qui. Ma stavo usando l'attributo name dall'inizio. Vediamo qual è il problema.
Saif Al Falah,

6

Non dovresti usare app.use (express.bodyParser ()) . BodyParser è un'unione di json + urlencoded + mulitpart. Non dovresti usarlo perché multipart verrà rimosso in connect 3.0.

Per risolverlo, puoi farlo:

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

È molto importante sapere che app.use (app.router) dovrebbe essere usato dopo il codice json e codificato, altrimenti non funziona!


4

Lo streaming delle richieste ha funzionato per me

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

var postdata = "";
req.on('data', function(postdataChunk){
    postdata += postdataChunk;
});

1
Meglio che non fare postdata.split("&")sarebbe quella di caricare il modulo di base querystring = require('querystring')e quindi analizzare il vostro postdatacon querystring.parse(postdata);
John Slegers,

4

Ho trovato tutti i parametri utilizzando il seguente codice per entrambe le richieste 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));
})

ti dispiace aggiornare la risposta con la tua versione di express?
lfender6445,

3

Scritto in Express versione 4.16

All'interno della funzione router è possibile utilizzare la req.bodyproprietà per accedere alla variabile post. Ad esempio, se questo fosse il POSTpercorso del modulo, restituirebbe ciò che hai inserito:

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

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

PS per coloro che hanno familiarità con PHP: per accedere alla $_GETvariabile PHP che utilizziamo req.querye per accedere alla $_POSTvariabile PHP usiamo req.bodyin Node.js.


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

1

I parametri postali possono essere recuperati come segue:

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

2
ti rendi conto che non funzionerà? paramviene utilizzato per le richieste GET .. non POST e il tuo esempio manca di dettagli, molto confuso per i nuovi arrivati. E soprattutto request.paramè deprecato, quindi il tuo esempio è sbagliato su così tanti livelli.
vdegenne,

0

Stai usando req.query.postcon il metodo sbagliato req.query.postfunziona method=get, method=postfunziona con body-parser .

Prova questo cambiando post per ottenere :

<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 nel codice espresso usa 'app.get'


0

Usa il pacchetto 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');
});
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.