yayınlarda req.body boş


257

Birdenbire bu, tüm projelerime oldu.

Ne zaman express ve body-parser kullanarak nodejs bir yazı yapmak req.bodyboş bir nesnedir.

var express    = require('express')
var bodyParser = require('body-parser')

var app = express()

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded())

// parse application/json
app.use(bodyParser.json())

app.listen(2000);

app.post("/", function (req, res) {
  console.log(req.body) // populated!
  res.send(200, req.body);
});

Ajax ve postacı aracılığıyla her zaman boştur.

Ancak kıvrılma yoluyla

$ curl -H "Content-Type: application/json" -d '{"username":"xyz","password":"xyz"}' http://localhost:2000/

amaçlandığı gibi çalışır.

İlkinde manuel olarak ayarlamayı denedim Content-type : application/jsonama her zaman400 bad request

Bu beni deli ediyor.

Vücut ayrıştırıcısında güncellenmiş bir şey olduğunu düşündüm ama indirgedim ve yardımcı olmadı.

Herhangi bir yardım takdir, teşekkürler.


16
Content-TypePostacıya açıkça ayarlamayı denedin mi? Değilse, daha önce postacı göndermeyen bir sorun yaşadığım için bunu deneyebilirsiniz Content-Type.
mscdex

Evet yaptım. 400 aldığımda: geçersiz json
Joseph Dailey

@mscdex - teşekkürler postacıda içerik tüpü ayarlamadı ve çılgına dönüyordu :)
Muzafar Ali

API'larından dosya göndermek / yüklemek istedikleri için buraya gelen ve bu nedenle form verilerini kullanmak zorunda olanlar için. Form verilerini işlemek için bir şeye ihtiyacınız var: npmjs.com/package/multer oldukça popüler bir paket.
bhaskar

Ne olursa olsun, postacı tamsayılarla ve float değerleriyle çok iyi başa çıkmaz. Eğer tamsayı veya kayan nokta değerleriniz varsa, her iki anahtar ve değer için iki kez alıntı yaptığınızdan emin olun
anabeto93 15

Yanıtlar:


272

İçerik türü için kullanılabilen 3 seçeneğin Postacı'da "X-www-form-urlencoded" öğesini seçin ve çalışması gerekir.

Ayrıca hata mesajının değiştirilmesinden kurtulmak için:

app.use(bodyParser.urlencoded())

İle:

app.use(bodyParser.urlencoded({
  extended: true
}));

Bkz. Https://github.com/expressjs/body-parser

'Body-parser' ara katman yazılımı çok parçalı değil yalnızca JSON ve urlen kodlanmış verileri işler


Postacı için işe yaradı, hiçbir şeyi değiştirmediğim için neden ajax ile çalıştığından emin değilim.
Joseph Dailey

Bazı nedenlerden dolayı Angular üzerinden http gönderilerinin URL kodlaması gerekmiyordu, ancak ajax çağrıları gerekliydi. Nedenini bilen var mı?
youngrrrr

Bu benim için çalıştı, neden ham kodlanmış ile çalışmadı?
Daniel Kobe

9
şimdi vücut ayrıştırıcı express.js ile dahili sadece kullanınapp.use(express.json());
Sujeet Agrahari

Çok teşekkür ederim! Bu uzun süredir cevaplanmış olmasına rağmen, yine de konuyla ilgilidir.
Spray'n'Pray

218

Postacı ile, HTTP posta işlemlerini ham JSON veri yükü ile test etmek için rawseçeneği seçin ve aşağıdaki başlık parametrelerini ayarlayın:

Content-Type: application/json

Ayrıca, JSON yükünüzde anahtar / değer olarak kullanılan tüm dizeleri çift tırnak içine aldığınızdan emin olun.

body-parserPaket gayet çok satırlı ham JSON yükleri ayrıştırmak olacaktır.

{
    "foo": "bar"
}

Aşağıdaki kurulumla Postman v0.8.4.13 uzantısı ( body-parserv1.12.2 ve expressv4.12.3) ile Chrome v37 ve v41'de test edilmiştir :

var express = require('express');
var app = express();
var bodyParser = require('body-parser');

// configure the app to use bodyParser()
app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(bodyParser.json());

// ... Your routes and methods here

Postacı ham json yükü


Ah adamım, düzgün biçimlendirilmiş bir JSON nesnesi yerine bir JS nesnesi değişmezi yapıştırdığımı nasıl özledim ...: -S ... teşekkürler arkadaşım!
Wes Johnson

Çift tırnak içinde anahtar / değer olarak kullanılan herhangi bir dizeleri sarma ... Kaçırmak kolay ama aksi takdirde toplam anlaşma kırıcı! Teşekkür ederim.
loxyboi

Ekran görüntülerinin iyi kullanımı.
Xan-Kun Clark-Davis

Postman'da form-dataveri göndermek için kullandığımda , her zaman {}req.body'de alıyorum. Content-TypeSeçeneği belirlemeli miyim ?
mingchau

56

Gerçekten aptalca bir hata yaptım ve namehtml dosyamdaki girdiler için öznitelikleri tanımlamayı unuttum .

Yani yerine

<input type="password" class="form-control" id="password">

Bu bende var.

<input type="password" class="form-control" id="password" name="password">

Şimdi request.bodyşöyle doldurulur:{ password: 'hhiiii' }


1
Bam. Sorun buydu. Teşekkürler!
Matt West

Tam olarak benim sorunumdu, isim değerleri olmayan bir form girişi, anlamaya çalışmak için saatler harcadı. Teşekkürler.
karensantana

37

İçerik türü ile gönderirken işe yaradığını keşfettim

"Application / json"

sunucu tarafı ile birlikte

app.use(bodyParser.json());

Şimdi üzerinden gönderebilirim

var data = {name:"John"}
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("POST", theUrl, false); // false for synchronous request
xmlHttp.setRequestHeader("Content-type", "application/json");
xmlHttp.send(data);

ve sonuç request.body.namesunucuda bulunur.


Puanınız için teşekkürler. Herhalde doğru içerik türünü göndermeniz gerektiğinden, en basit çözüm olmasa da, bunun en temiz olduğunu düşünüyorum. Bence.
Xan-Kun Clark-Davis

işte cevap!
Jel

Benim durumumda değiştirmek zorunda kaldımxmlHttp.send(JSON.stringify(data));
endo64

18

Bugün bu problemle karşılaştım ve Postman'daki içerik türü başlığını kaldırmanın sorunu düzeltildi ! Çok ilginç. Birine yardımcı olması durumunda buraya eklemek.

BeerLocker eğitimini burada takip ediyordum: http://scottksmith.com/blog/2014/05/29/beer-locker-building-a-restful-api-with-node-passport/


2
aynı sorunu yaşadım. başlık "işaretlenmemiş" (ve gri) sahip olması yeterli değildi, tamamen kaldırmak zorunda kaldı. "</>" kaynak düğmesi, Content-Type öğesinin denetlenmemiş durumdayken bu başlığı göndermediğimi gösterse de, yine de tamamen kaldırılması gerekiyordu.
theRemix

Postacı krom uzantısındaki varsayılan başlıkları nasıl kaldıracağımı anlayamıyorum ... belki uygulamayı kullanıyor musunuz?
WestleyArgentum

Oh, uygulamayı yükledim ve uzantıdan çok daha iyi çalışıyor. Gürültü için üzgünüm.
WestleyArgentum

12

Gövde ayrıştırıcı ara katman yazılımının istek türüne (json, urlencoded) uygun şekilde ayarlanıp ayarlanmadığını kontrol etmelisiniz.

Ayarladıysanız,

app.use(bodyParser.json());

postacıda verileri ham olarak göndermeniz gerekir.

https://i.stack.imgur.com/k9IdQ.png postman ekran görüntüsü

Ayarladıysanız,

app.use(bodyParser.urlencoded({
    extended: true
}));

ardından 'x-www-form-urlencoded' seçeneği seçilmelidir.


ikisine sahip olmak ne olacak? (bodyParser.urlencoded ve bodyParser.json ()) ... postacıda hangisini kullanabilirim?
TommyLeong

9

Benim sorunum ilk önce rotayı oluşturmaktı

// ...
router.get('/post/data', myController.postHandler);
// ...

ve rotadan sonra ara katman yazılımını kaydetme

app.use(bodyParser.json());
//etc

Uygulama yapısı ve kopyalanması ve örneklerden birlikte projenin yapıştırılması nedeniyle.

Bir kez rota önce ara katman yazılımı kaydetmek için sipariş sabit, hepsi çalıştı.


teşekkürler fiat, doğru sipariş ile ve ham sekmeyi kullanarak sonunda benim için çalıştı
Alex

4

Ben web-app üzerinden öğrenmeye başladığım ilk kez node.js öğrenirken bile, tüm bu şeyleri formumda iyi bir şekilde yapıyordum, yine de sonrası isteğinde değerler alamadım. Uzun hata ayıklama sonra, ben hangi formda ben enctype="multipart/form-data"değerleri alamadım nedeniyle vermiş olduğunu bilmek geldi . Sadece kaldırdım ve benim için çalıştı.


Evet, bu da form gövdesi almak için çalıştı ama sonra enctype="multipart/form-data"
formumla

btw, sadece yukarıdaki yorumuma eklemek için, bu çalışmayı başardımmulter
npmjs.com/package/multer

3

Herhangi bir encType (varsayılan application/x-www-form-urlencoded) kullanmazsanız, metin giriş alanlarına sahip olursunuz, ancak dosya alamazsınız.

Metin girişi ve dosya göndermek istediğiniz bir formunuz varsa, multipart/form-datakodlama türünü kullanın ve buna ek olarak multerara katman yazılımı kullanın . Multer, istek nesnesini ayrıştırır ve req.filesizin için hazırlanır ve diğer tüm giriş alanları kullanılabilir req.body.


1
teşekkürler - multergerçekten benim sorunumun çözümü oldu. Cevabınızın bir parçası olarak bunu nasıl kullanacağınıza dair bir örnek ekleyebilmeniz iyi olur
tsando

2

Benzer bir sorun da başıma geldi, basitçe geri arama parametrelerini karıştırdım. Geri arama işlevlerini doğru sırada ayarladığınızdan emin olun. En azından aynı sorunu yaşayan herkes için.

router.post('/', function(req, res){});

2

["Key": "type", "value": "json"] & ["key": "Content-Type", "value": "application / x-www-form-urlencoded"] öğenizin postacı istek üstbilgileri


2

Bunu multeryukarıda önerildiği gibi kullanarak çözdüm, ancak bunun nasıl yapılacağı hakkında tam bir çalışma örneği vermeyi kaçırdılar. Temelde bu, bir form grubunuz olduğunda olabilir enctype="multipart/form-data". İşte sahip olduğum formun HTML'si:

<form action="/stats" enctype="multipart/form-data" method="post">
  <div class="form-group">
    <input type="file" class="form-control-file" name="uploaded_file">
    <input type="text" class="form-control" placeholder="Number of speakers" name="nspeakers">
    <input type="submit" value="Get me the stats!" class="btn btn-default">            
  </div>
</form>

Ve burada nasıl kullanacağınız multerile bu formun değerleri ve isimleri almak Express.jsve node.js:

var multer  = require('multer')
var upload = multer({ dest: './public/data/uploads/' })
app.post('/stats', upload.single('uploaded_file'), function (req, res) {
   // req.file is the name of your file in the form above, here 'uploaded_file'
   // req.body will hold the text fields, if there were any 
   console.log(req.file, req.body)
});

1

Birkaç dakika önce aynı problemi yaşadım, yukarıdaki cevaplarda mümkün olan her şeyi denedim ama herhangi biri çalıştı.

Yaptığım tek şey yükseltme Node JS sürümü, yükseltme bir şey etkileyebilir bilmiyordum, ama oldu.

Node JS sürümünü 10.15.0(en son sürüm) yükledim , geri döndüm 8.11.3ve şimdi her şey çalışıyor. Belki body-parsermodül bu konuda bir düzeltme yapmalıdır.


1

Girişimde isim yoktu ... isteğim boştu ... bittiğine memnun oldum ve kodlamaya devam edebilirim. Herkese teşekkürler!

Cevap Jason Kim tarafından kullandım:

Yani yerine

<input type="password" class="form-control" id="password">

bu bende var

<input type="password" class="form-control" id="password" name="password">

1

JSON.stringify(data)aşağıdaki gibi AJAX ile gönderirken yapmamalısınız .

Bu doğru kod DEĞİLDİR:

function callAjax(url, data) {
    $.ajax({
        url: url,
        type: "POST",
        data: JSON.stringify(data),
        success: function(d) {
            alert("successs "+ JSON.stringify(d));
        }
    });
}   

Doğru kod:

function callAjax(url, data) {
    $.ajax({
        url: url,
        type: "POST",
        data: data,
        success: function(d) {
            alert("successs "+ JSON.stringify(d));
        }
    });
}

Burada dikkat edilmesi gereken en önemli nokta, "POST" yazdığınızdan emin olmanızdır. Ben sadece "post" kullanmanın boş req.body yol açtı örnekleri gördüm.
Matt C.

1

Postacı ile yapıyorsanız, lütfen API talep ederken bu şeyleri onaylayın

resim açıklamasını buraya girin


0

Ekspres yerine restify kullanıyordum ve aynı problemle karşılaştım. Çözüm:

server.use(restify.bodyParser());


0

Change app.use(bodyParser.urlencoded());Kodunuzdaki için

app.use(bodyParser.urlencoded({extended : false}));

ve postacıda, başlıkta Content-Typedeğeri olarak application/x-www-form-urlencodeddeğiştirapplication/json

Ta :-)


0

Harika cevaplarınız için hepinize teşekkürler! Bir çözüm aramak için biraz zaman geçirdim ve benim tarafımda temel bir hata yapıyordum bodyParser.json(): Fonksiyonun içinden çağırıyordum :

app.use(['/password'], async (req, res, next) => {
  bodyParser.json()
  /.../
  next()
})

Sadece yapmam gerekiyordu app.use(['/password'], bodyParser.json())ve işe yaradı ...


0

Postacıda, kabul edilen cevabı izledikten sonra bile, boş bir talep gövdesi alıyordum. Sorunun, adlı bir üstbilgiyi geçmediği ortaya çıktı

Content-Length : <calculated when request is sent>

Bu başlık, varsayılan olarak (diğer 5 kullanıcıyla birlikte) devre dışı bıraktığım şekilde mevcuttu. Bunu etkinleştirin ve istek gövdesini alacaksınız.


0

Benim sorunum ilk require("./routes/routes")(app); önce kodun sonuna kaydırdı rota oluşturmak oldu app.listen ve çalıştı!


0

Zaten sorunu çözdü, ama birine yardımcı olabilir.

Form öğelerinizin her birinin kendisiyle ilişkilendirilmiş bir adı olduğunu görün. Yaptığım hata buydu ...!

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.