Jak pobrać parametry zapytania POST?

768

Oto moja prosta forma:

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

Oto mój kod Express.js /Node.js:

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

Próbowałem sReq.query.emaillub sReq.query['email']lub sReq.params['email']itp żaden z nich pracy. Wszyscy wracają undefined.

Po zmianie na połączenie Get działa, więc .. masz jakiś pomysł?

murvinlai
źródło
33
BEZPIECZEŃSTWO : każdy, kto korzysta bodyParser()z odpowiedzi tutaj, powinien również przeczytać odpowiedź
@SeanLynch

Odpowiedzi:

1250

Wszystko się zmieniło od uruchomienia Express 4.16.0 , możesz teraz używać express.json()i express.urlencoded()tak jak w Express 3.0 .

To było inne, począwszy od Express 4.0 do 4.15 :

$ npm install --save body-parser

i wtedy:

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

Reszta jest jak w Express 3.0 :

Najpierw musisz dodać oprogramowanie pośrednie, aby przeanalizować dane postu treści.

Dodaj jeden lub oba z następujących wierszy kodu:

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

Następnie w swoim module obsługi użyj req.bodyobiektu:

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

Pamiętaj, że użycie express.bodyParser()nie jest zalecane.

app.use(express.bodyParser());

...jest równa:

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

Istnieją obawy dotyczące bezpieczeństwa express.multipart(), dlatego lepiej jest jawnie dodać obsługę określonych typów kodowania, których potrzebujesz. Jeśli potrzebujesz kodowania wieloczęściowego (na przykład w celu obsługi przesyłania plików), powinieneś to przeczytać .

Drew Noakes
źródło
76
Jeśli ta odpowiedź nie działa poprawnie, upewnij się, że masz content-typeustawiony nagłówek, na przykład:curl -d '{"good_food":["pizza"]}' -H 'content-type:application/json' "http://www.example.com/your_endpoint"
SooDesuNe
6
Jaka jest różnica między publikowaniem formularza zawierającego pary nazwa / wartość a publikowaniem treści JSON? Czy oba pojawiają się w grupie wymagającej?
chovy
7
@ chovy Tak, robią. bodyParserwyodrębnia JSON, dane zakodowane w adresie URL i dane wieloczęściowe w req.bodyobiekcie.
Kristján
7
Ten kod dawał mi błędy, ponieważ oprogramowanie pośrednie nie jest już dołączane do Express; będziesz musiał użyć body-parsera: github.com/senchalabs/connect#middleware
araneae
11
Do odczytu jsona za pomocą Express 4 app.use(require('body-parser').json())wystarczy tylko linia. Następnie możesz odczytać dane json z obiektu treści żądania, tj. req.bodyZ definicji trasy.
Martin Carel
90

Kwestia bezpieczeństwa przy użyciu express.bodyParser ()

Podczas gdy wszystkie inne odpowiedzi obecnie zalecane przy użyciu express.bodyParser()oprogramowania pośredniczącego, to faktycznie owinięcie wokół express.json(), express.urlencoded()i express.multipart()middleware ( http://expressjs.com/api.html#bodyParser ). Parsowanie treści żądań formularzy odbywa się przez express.urlencoded()oprogramowanie pośrednie i jest to wszystko, czego potrzebujesz do ujawnienia danych formularza na req.bodyobiekcie.

Ze względu na obawy dotyczące bezpieczeństwa związane z tym, w jaki sposób express.multipart()/ connect.multipart()tworzy pliki tymczasowe dla wszystkich przesyłanych plików (i nie są usuwane), zaleca się teraz, aby nie używać express.bodyParser()opakowania, ale zamiast tego używać tylko potrzebnych plików pośrednich.

Uwaga: connect.bodyParser()wkrótce zostanie zaktualizowany, aby obejmował tylko urlencodedi jsonwydanie Connect 3.0 (które rozszerza Express).


Krótko mówiąc, zamiast ...

app.use(express.bodyParser());

...powinieneś użyć

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

a jeśli / kiedy musisz obsługiwać formularze wieloczęściowe (przesyłanie plików), użyj biblioteki innej firmy lub oprogramowania pośredniego, takiego jak multiparty, busboy, dicer itp.

Sean Lynch
źródło
Dodano komentarz poniżej pytania, aby więcej osób widziało Twoje obawy i porady. Czy inne rozwiązania wyszczególnione w poście na blogu Andrew Kelleya (nadal) są według Ciebie istotne? (tylko pytam o inne, moje potrzeby dotyczą wyłącznie narzędzi wewnętrznych ^^)
FelipeAls,
@FelipeAls - Tak, i chciałem również odnieść się do postu Andrew. Każda z tych sugestii (z uwzględnieniem wad każdej z nich) jest istotna.
Sean Lynch,
Ponadto, gdy Connect 3.0 zostanie wydany bez uwzględnienia multipart()jako część bodyParser(), bodyParser()ponownie stanie się „bezpieczny”, ale będziesz musiał jawnie włączyć obsługę wielu części za pomocą biblioteki innej firmy.
Sean Lynch
84

Uwaga : ta odpowiedź dotyczy Express 2. Zobacz tutaj Express 3.

Jeśli używasz Connect / Express, powinieneś użyć oprogramowania pośredniego bodyParser : Jest to opisane w przewodniku 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
});

Oto oryginalna wersja tylko do połączenia:

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

Zarówno kwerenda, jak i treść są analizowane przy użyciu obsługi parametrów w stylu Rails ( qs), a nie biblioteki niskiego poziomuquerystring . W celu analizowania parametrów z powtarzających się qs, parametr musi mieć wsporniki: name[]=val1&name[]=val2. Obsługuje również mapy zagnieżdżone. Oprócz analizowania przesłanych formularzy HTML bodyParser może automatycznie analizować żądania JSON.

Edycja : Przeczytałem na express.js i zmodyfikowałem moją odpowiedź, aby była bardziej naturalna dla użytkowników Express.

Yonran
źródło
Hmm ok. próbuję bodyParser (). dokument mówi, że mogę go pobrać z req.query (), ale nic nie mam. to bardzo dziwne. Nie mam problemu z Get tho.
murvinlai,
3
Nie, zapytanie jest WYŁĄCZNIE parametrami GET. Dane POST są pobierane przez osobę wymagającą. Funkcja req.params () obejmuje je oba.
yonran
Przypadkowe kliknięcie zanotowało tę odpowiedź przypadkowo, bez mojej uwagi! Teraz StackOverflow nie pozwoli mi tego zmienić. Esp. frustrujące, ponieważ było to pomocne ... Głosowałem za kolejną z twoich dobrych odpowiedzi, których nie chciałem wyraźnie nadrobić. :)
HostileFork mówi: nie ufaj SE
33

To zrobi, jeśli chcesz zbudować wysłane zapytanie bez oprogramowania pośredniego:

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

});

To wyśle ​​to do przeglądarki

email=emailval&password1=pass1val&password2=pass2val

Prawdopodobnie lepiej jest jednak użyć oprogramowania pośredniego, więc nie musisz zapisywać tego w kółko na każdej trasie.

med116
źródło
3
sooo .... przydatne dla tych, którzy nie chcą polegać na bibliotece, która prędzej czy później zostanie uznana za przestarzałą
Daniel
możesz łatwo zbudować własne oprogramowanie pośrednie
maioman
To świetna odpowiedź, ale dlaczego jest dodatkowy tekst ”---------------------------- 359856253150893337905494 Dyspozycja treści: dane formularza; nazwa = "fullName" Ram ---------------------------- 359856253150893337905494-- "Nie chcę tego numeru.
Nawaraj
25

Uwaga dla użytkowników Express 4:

Jeśli spróbujesz umieścić app.use(express.bodyParser());w swojej aplikacji, podczas próby uruchomienia serwera Express pojawi się następujący błąd:

Błąd: większość oprogramowania pośredniego (takiego jak bodyParser) nie jest już dostarczana w pakiecie z Express i musi być instalowana osobno. Zobacz https://github.com/senchalabs/connect#middleware .

Będziesz musiał zainstalować pakiet body-parserosobno od npm , a następnie użyj czegoś takiego: (przykład wzięty ze strony 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
źródło
Bardzo dziękuję za tę informację. Wyciągałem włosy, próbując uporać się z nowym sposobem korzystania z bodyParser! To był wielki przełom - naprawdę doceniam
Tommy
1
heplp: body-parser przestarzałe bodyParser: użyj indywidualnych plików pośrednich json / urlencoded
Mohammad Faizan khan
19

Biorąc pod uwagę jakąś formę:

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

Korzystanie z ekspresu

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

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

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

Wynik:

{"name":"x","description":"x"}
req.param.name x
David
źródło
6
nie działało dla mnie. trzeba użyć app.use (express.bodyParser ());
cawecoy
@cawecoy absolutnie słusznie tutaj samo, ale express.bodyParser () nie działa również dla mnie to przestarzałe
Mohammad Faizan khan
@MohammadFaizankhan to była praca eksperymentalna, nie używałem już ekspresu, nie mogę teraz pomóc. Google dla podobnych funkcji do express.bodyParser (). powodzenia!
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);
});

Frontend:

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
});
jeziora
źródło
15
app.use(express.bodyParser());

Następnie na app.postżądanie można uzyskać wartości postów za pośrednictwem req.body.{post request variable}.

Chinthaka Senanayaka
źródło
twoją zmienną żądania postu jest tutaj, czy jest to identyfikator pola wejściowego, o którym mowa, czy całego formularza, czy co?
Eogcloud,
2
express.bodyParser () jest przestarzały. zaktualizuj swoją odpowiedź
Mohammad Faizan khan
15

Aktualizacja dla Express 4.4.1

Poniższe oprogramowanie pośrednie zostało usunięte z programu Express.

  • bodyParser
  • json
  • urlencoded
  • wieloczęściowy

Gdy używasz oprogramowania pośredniego bezpośrednio tak, jak w Express 3.0. Otrzymasz następujący błąd:

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


Aby korzystać z oprogramowania pośredniego, musisz teraz zrobić npm dla każdego oprogramowania pośredniego osobno.

Ponieważ bodyParser jest oznaczony jako przestarzały, dlatego polecam następujący sposób, używając json, urlencode i parsera wieloczęściowego, np. Formidable, connect-multiparty. (Oprogramowanie pośrednie Multipart jest również przestarzałe).

Pamiętaj również, że po zdefiniowaniu urlencode + json dane formularza nie zostaną przeanalizowane, a żądanie będzie niezdefiniowane. Musisz zdefiniować oprogramowanie pośrednie obsługujące żądanie wieloczęściowe.

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
źródło
Myślę, że to naprawdę zła aktualizacja funkcji
Mohammad Faizan khan
tylko ze względu na analizę ciała muszę zrobić dużo kodu. czym jest hack
Mohammad Faizan khan
1
Musiałem dodać „.middleware ()”, aby wymagać („json-middleware”), aby działało.
DustinB
8

Dla Express 4.1 i nowszych

Ponieważ większość odpowiedzi używa Express, bodyParser, connect; gdzie multipart jest przestarzałe. Istnieje bezpieczny sposób łatwego wysyłania obiektów wieloczęściowych.

Multer może być używany jako zamiennik metody connect.multipart ().

Aby zainstalować pakiet

$ npm install multer

Załaduj go do swojej aplikacji:

var multer = require('multer');

Następnie dodaj go do stosu oprogramowania pośredniego wraz z innym narzędziem do analizowania oprogramowania pośredniego.

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

connect.json () obsługuje aplikację / json

connect.urlencoded () obsługuje aplikację / x-www-form-urlencoded

multer () obsługuje dane wieloczęściowe / formularze

Lalit Umbarkar
źródło
8

Dokładnie szukałem tego problemu. Postępowałem zgodnie ze wszystkimi powyższymi wskazówkami, ale wymaganie: wciąż zwracałem pusty obiekt {}. W moim przypadku było to tak proste, jak niepoprawny HTML.

W formularzu HTML upewnij się, że używasz 'name'atrybutu w tagach wejściowych, nie tylko 'id'. W przeciwnym razie nic nie zostanie przeanalizowane.

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

Mój błąd idioto jest twoją korzyścią.

cwingrav
źródło
Mam ten sam problem. Ale od początku korzystałem z atrybutu name. Zobaczmy, na czym polega problem.
Saif Al Falah
6

Nie powinieneś używać app.use (express.bodyParser ()) . BodyParser to połączenie json + urlencoded + mulitpart. Nie powinieneś tego używać, ponieważ multipart zostanie usunięty w Connect 3.0.

Aby rozwiązać ten problem, możesz to zrobić:

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

Bardzo ważne jest, aby wiedzieć, że app.use (app.router) powinien być używany po jsonie i urlencodowany, w przeciwnym razie nie zadziała!

HenioJR
źródło
4

Żądanie przesyłania strumieniowego działało dla mnie

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

var postdata = "";
req.on('data', function(postdataChunk){
    postdata += postdataChunk;
});
zeah
źródło
1
Lepiej postdata.split("&")byłoby załadować moduł podstawowy, querystring = require('querystring')a następnie przeanalizować postdatago querystring.parse(postdata);
John Slegers
4

Mogłem znaleźć wszystkie parametry, używając następującego kodu dla żądań POST i 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
źródło
czy masz coś przeciwko aktualizacji odpowiedzi w swojej wersji express?
lfender6445
3

Napisane w wersji Express 4.16

Wewnątrz funkcji routera można użyć req.bodywłaściwości, aby uzyskać dostęp do zmiennej post. Na przykład, jeśli była to POSTtrasa twojego formularza, odesłałbyś to, co wpisałeś:

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

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

PS dla tych, którzy znają PHP: Aby uzyskać dostęp do $_GETzmiennej PHP, której używamy, req.queryi aby uzyskać dostęp do $_POSTzmiennej PHP używamy req.bodyw Node.js.

Logan
źródło
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
źródło
1

Parametry posta można pobrać w następujący sposób:

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
źródło
1
zdajesz sobie sprawę, że to nie zadziała? paramjest używany do żądań GET .. nie POST, a twój przykład nie zawiera szczegółów, co jest bardzo mylące dla początkujących. Co więcej, request.paramjest to właściwie przestarzałe, więc twój przykład jest błędny na tak wielu poziomach.
vdegenne
0

Używasz req.query.postmetodą niewłaściwych req.query.postprac z method=get, method=postprac z ciała parsera .

Spróbuj tego, zmieniając wpis, aby uzyskać :

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

W kodzie ekspresowym użyj „app.get”

sagar saini
źródło
0

Użyj pakietu 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
źródło