POST sorgu parametreleri nasıl alınır?


768

İşte benim basit formum:

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

İşte Express.js /Node.js kodum:

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

Denedim sReq.query.emailya sReq.query['email']da sReq.params['email'], vb. Hiçbiri çalışmıyor. Hepsi geri dönüyor undefined.

Bir Get çağrısına geçtiğimde işe yarıyor, yani .. herhangi bir fikir?


33
GÜVENLİK : bodyParser()Buradaki yanıtları kullanan herkes aşağıdaki
@SeanLynch'in

Yanıtlar:


1251

Yapılacaklar gelmiş değişti yeniden başlıyor kez Express 4.16.0 , artık kullanabilirsiniz express.json()ve express.urlencoded()sadece olduğu gibi Express 3.0 .

Bu oldu , farklı başlangıç 4,15 için Express 4.0 :

$ npm install --save body-parser

ve sonra:

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

Gerisi Express 3.0'daki gibidir :

Öncelikle, vücudun posta verilerini ayrıştırmak için bazı ara katmanlar eklemeniz gerekir.

Aşağıdaki kod satırlarından birini veya her ikisini ekleyin:

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

Ardından, işleyicinizde req.bodynesneyi kullanın :

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

Kullanılması express.bodyParser()tavsiye edilmez.

app.use(express.bodyParser());

... şuna eşittir:

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

Güvenlikle ilgili endişeler mevcuttur express.multipart()ve bu nedenle, gereksinim duyduğunuz belirli kodlama türleri için açıkça destek eklemek daha iyidir. Çok parçalı kodlamaya ihtiyacınız varsa (örneğin dosya yüklemeyi desteklemek için) bunu okumalısınız .


76
Bu yanıt düzgün çalışmıyorsa, content-typebaşlık ayarını yaptığınızdan emin olun , örneğin:curl -d '{"good_food":["pizza"]}' -H 'content-type:application/json' "http://www.example.com/your_endpoint"
SooDesuNe

6
isim / değer çiftleri içeren bir form gönderme ile JSON gövdesi gönderme arasındaki fark nedir? İkisi de req.body'de mi ortaya çıkıyor?
chovy

7
@chovy Evet, var. bodyParserJSON, URL kodlu ve çok parçalı verileri req.bodynesneye özetler .
Kristján

7
Middleware artık Express ile birlikte gelmediğinden bu kod bana hata verdi; body-parser kullanmanız gerekecek: github.com/senchalabs/connect#middleware
araneae

11
Express 4 kullanarak json okumak için sadece app.use(require('body-parser').json())satır yeterlidir. Ve sonra json verilerini isteğinizin gövde nesnesinden, yani req.bodybir rota tanımının içinden okuyabilirsiniz .
Martin Carel

90

Express.bodyParser () kullanarak güvenlik sorunu

Diğer tüm cevaplar anda kullanmakta tavsiye ederken express.bodyParser()ortakatmanını, bu aslında etrafında sarıcı express.json(), express.urlencoded()ve express.multipart()ara katman ( http://expressjs.com/api.html#bodyParser ). Form istek gövdelerinin ayrıştırılması, express.urlencoded()ara katman yazılımı tarafından yapılır ve form verilerinizi req.bodynesneye göstermeniz için gereken her şeydir .

Yüklenen tüm dosyalar için geçici dosyaların nasıl oluşturulduğu / oluşturulduğu (ve çöp toplanmadığı) ile ilgili bir güvenlik endişesi nedeniyle , artık sargıyı kullanmamanız, bunun yerine yalnızca ihtiyacınız olan ara araçları kullanmanız önerilir .express.multipart()connect.multipart()express.bodyParser()

Not: connect.bodyParser()Yakında sadece içerecek şekilde güncellenecek urlencodedve jsonBağlan 3.0 (Ekspres genişleten) bırakıldığında.


Kısacası, yerine ...

app.use(express.bodyParser());

...kullanmalısın

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

ve çok parçalı formları (dosya yüklemeleri) işlemeniz gerekiyorsa / ne zaman gerekiyorsa, bir üçüncü taraf kütüphanesi veya çok partili, busboy, dicer vb.


Daha fazla insanın endişelerinizi ve tavsiyelerinizi görmesi için sorunun altına bir yorum eklendi. Andrew Kelley blog yazısında (hala) ayrıntılı olarak açıklanan diğer çözümler sizin görüşünüzle alakalı mı? (sadece başkalarını sormak, benim ihtiyaçlarım sadece iç aletler için ^ ^)
FelipeAls

@FelipeAls - Evet, ben de Andrew'un gönderisine atıfta bulunmak istedim. Bu önerilerden herhangi biri (her birinin çöküşünü dikkate alarak) önemlidir.
Sean Lynch

Ayrıca Connect'e 3.0 kez eklemeden salınır multipart()bir parçası olarak bodyParser(), bodyParser()"güvenli" bir daha olur, ancak açıkça bir üçüncü taraf kitaplığı kullanarak çok parçalı desteğini etkinleştirmek için ihtiyacınız olacak.
Sean Lynch

84

Not : bu cevap Express 2 içindir. Express 3 için buraya bakın .

Connect / express kullanıyorsanız, bodyParser ara katman yazılımını kullanmalısınız : Expressjs kılavuzunda açıklanmıştır .

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

İşte yalnızca bağlanan orijinal sürüm:

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

Hem sorgu dizesi hem de gövde , düşük düzey kitaplık yerine Rails stili parametre işleme ( qs) kullanılarak ayrıştırılır . İle tekrarlanan parametrelerin ayrıştırmak için , parametre parantez sahip olması gerekir: . İç içe haritaları da destekler. HTML form gönderimlerini ayrıştırmaya ek olarak, bodyParser JSON isteklerini otomatik olarak ayrıştırabilir.querystringqsname[]=val1&name[]=val2

Düzenleme : Express.js üzerinde okudum ve cevabımı Express kullanıcıları için daha doğal olacak şekilde değiştirdim.


Hmm tamam. bodyParser () 'ı deniyorum. doktor req.query () alabilirim ama hiçbir şeyim yok diyor. bu çok garip. Get tho ile bir sorunum yok.
murvinlai

3
Hayır, talep sorgusu SADECE GET parametreleridir. POST verilerini talep eden kişi aracılığıyla alabilirsiniz. Req.params () işlevi her ikisini de içerir.
yonran

Başıboş bir tıklama fark etmeden bu cevabı yanlışlıkla reddetti! Şimdi StackOverflow değiştirmeme izin vermiyor. Esp. Bu yardımcı oldu gibi sinir bozucu ... Açıkça telafi etmek için aramadım iyi cevaplar başka bir upvoted. :)
HostileFork SE

33

Yayınlanan sorguyu ara katman yazılımı olmadan oluşturmak istiyorsanız bunu yapar:

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

});

Bu tarayıcıya gönderir

email=emailval&password1=pass1val&password2=pass2val

Muhtemelen ara katman yazılımı kullanmak daha iyidir, bu yüzden bunu her rotada tekrar tekrar yazmak zorunda kalmazsınız.


3
sooo .... kullanışlı, er ya da geç kullanımdan kaldırılacak bir kütüphaneye güvenmek istemeyenler için
Daniel

kolayca kendi ara katman yazılımı inşa edebilirsiniz
maioman

Bu harika bir cevap ama neden fazladan metin var "---------------------------- 359856253150893337905494 İçerik-Eğim: form-veri; ad = "fullName" Ram ---------------------------- 359856253150893337905494-- "Bu numarayı istemiyorum.
Nawaraj

25

Express 4 kullanıcıları için not:

Eğer denemek ve koyarsanız app.use(express.bodyParser());uygulamanıza size Ekspres sunucusunu başlatmaya çalıştığınızda, aşağıdaki hatayı alırsınız:

Hata: Çoğu ara katman yazılımı (bodyParser gibi) artık Express ile birlikte gelmemektedir ve ayrı olarak yüklenmesi gerekir. Lütfen https://github.com/senchalabs/connect#middleware adresine bakın .

Paketi npm'denbody-parser ayrı olarak kurmanız ve ardından aşağıdakine benzer bir şey kullanmanız gerekir (örnek GitHub sayfasından alınmıştır ):

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

Bu bilgi için çok teşekkürler. BodyParser'ı kullanmanın yeni yolu ile uğraşmaya çalışırken saçlarımı çekiyordum! Bu büyük bir atılımdı - gerçekten takdir ediyorum
Tommy

1
heplp: body-parser kullanımdan kaldırılmış bodyParser: bireysel json / urlencoded middlewares kullanın
Mohammad Faizan khan

19

Bazı formlar verildiğinde:

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

Express kullanma

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

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

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

Çıktı:

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

6
benim için çalışmadı. app.use (express.bodyParser ()) kullanmanız gerekir;
cawecoy

@cawecoy kesinlikle burada aynı ama express.bodyParser () benim için iyi çalışmıyor
Mohammad Faizan khan

@MohammadFaizankhan deneysel bir işti, artık ekspres kullanmadım, şimdi yardım edemem. Express.bodyParser () işlevine benzer işlevler için Google'ı kullanın. iyi şanslar!
cawecoy

16

Arka uç:

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

Başlangıç ​​aşaması:

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

Sonra app.postistek için posta yoluyla değerleri alabilirsiniz req.body.{post request variable}.


Buradaki yazı isteği değişkeniniz, söz konusu giriş alanının kimliği mi yoksa tüm form mu yoksa ne?
Eogcloud

2
express.bodyParser () kullanımdan kaldırıldı. Cevabınızı güncelleyin
Mohammad Faizan khan

15

Express 4.4.1 Güncellemesi

Aşağıdakilerin orta yazılımı Express'ten kaldırılır.

  • bodyParser
  • json
  • urlencoded
  • Çok parçalı

Ara katman yazılımını doğrudan ifade 3.0'da yaptığınız gibi kullandığınızda. Aşağıdaki hatayı alırsınız:

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


Bu ara katman yazılımlarını kullanmak için, şimdi her ara katman yazılımı için ayrı ayrı npm yapmanız gerekir .

BodyParser kullanımdan kaldırılmış olarak işaretlendiğinden, json, urlencode ve çok parçalı ayrıştırıcıyı zorlu, connect-multiparty gibi kullanmanızı öneririz. (Çok parçalı ara yazılım da kullanımdan kaldırılmıştır).

Ayrıca, sadece urlencode + json'u tanımlayarak, form verileri ayrıştırılmayacak ve req.body tanımsız olacaktır. Çok parçalı isteği bir orta katman tanıtıcısı tanımlamanız gerekir.

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

sanırım bu gerçekten kötü bir özellik güncelleme
Mohammad Faizan khan

sadece vücut ayrışması uğruna çok fazla kod yapmak zorundayım. kesmek nedir
Mohammad Faizan khan

1
Bu işe almak için ('json-middleware') gerektiren ".middleware ()" eklemek zorunda kaldı.
DustinB

8

Express 4.1 ve üstü için

Cevapların çoğu Express için kullanıldığından, bodyParser, connect; burada çok parçalı kullanımdan kaldırılmıştır. Post çok parçalı nesneleri kolayca göndermenin güvenli bir yolu vardır.

Multer, connect.multipart () yerine kullanılabilir.

Paketi yüklemek için

$ npm install multer

Uygulamanıza yükleyin:

var multer = require('multer');

Ve sonra, diğer form ayrıştırma ara katmanı ile birlikte ara katman yığınına ekleyin.

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

connect.json () , application / json ile ilgilenir

connect.urlencoded () uygulama / x-www-form-urlencoded ile ilgilenir

multer () çoklu bölüm / form verilerini işler


8

Tam olarak bu problemi arıyordum. Yukarıdaki tüm tavsiyelere uyuyordum ama req.body hala boş bir nesne döndürüyordu {}. Benim durumumda, html'nin yanlış olması kadar basit bir şeydi.

Formunuzun html'sinde, 'name'özelliği yalnızca giriş etiketlerinizde kullandığınızdan emin olun 'id'. Aksi takdirde, hiçbir şey ayrıştırılmaz.

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

Benim aptal hatam senin yararın.


Burada da aynı problem. Ama ad özniteliğini en başından kullanıyordum. Sorunun ne olduğunu görelim.
Saif Al Falah

6

Kullanılacak shoudn't app.use (express.bodyParser ()) . BodyParser, json + urlencoded + mulitpart'ın birliğidir. Connect 3.0'da çok parçalı kaldırılacağı için bunu kullanmamalısınız.

Bu sorunu çözmek için şunları yapabilirsiniz:

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

Bunu bilmek çok önemlidir App.use (app.router) json sonra kullanılmalı ve urlencoded gerektiğini , aksi takdirde işe yaramaz!


4

Akış isteği benim için çalıştı

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

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

1
Yapmamaktan iyidir postdata.split("&")çekirdek modülü yüklemek için olurdu querystring = require('querystring')ve ardından ayrıştırma postdataile querystring.parse(postdata);
John Slegers

4

POST ve GET istekleri için aşağıdaki kodu kullanarak tüm parametreleri bulabilirim .

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

cevabı express sürümünüzle güncellemeyi düşünüyor musunuz?
lfender6445

3

Yazılı Express 4.16

Yönlendirici işlevinin içinde, req.bodyyazı değişkenine erişmek için özelliği kullanabilirsiniz . Örneğin POST, formunuzun rotası buysa, girdiğiniz bilgileri geri gönderir:

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

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

PHP'yi bilenler için PS: PHP'nin $_GETdeğişkenine req.queryerişmek ve Node.js'de $_POSTkullandığımız PHP değişkenine erişmek için kullanıyoruz req.body.


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

Post Parametreleri aşağıdaki gibi alınabilir:

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
bunun işe yaramayacağını biliyor musun? paramGET istekleri için kullanılır .. POST değil ve örnek ayrıntılar eksik, yeni gelenler için çok kafa karıştırıcı. Üstelik request.paramaslında kullanımdan kaldırılmıştır, bu nedenle örneğiniz birçok düzeyde yanlıştır.
vdegenne

0

Kullanıyorsunuz req.query.postyanlış yöntem ile req.query.postbirlikte eserleri method=get, method=postile eserler vücuda ayrıştırıcı .

Sadece değiştirerek bunu denemek yazı için olsun :

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

Ve ekspres kodda 'app.get' kullanın


0

Express-fileupload paketini kullanın :

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');
});
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.