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


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


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.


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.


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.


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

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

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

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


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

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


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


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!


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

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

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.


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

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

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”


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');
});
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.