Express.js req.body tanımsız


292

Bu benim Express sunucumun yapılandırması olarak var

app.use(app.router); 
app.use(express.cookieParser());
app.use(express.session({ secret: "keyboard cat" }));
app.set('view engine', 'ejs');
app.set("view options", { layout: true });
//Handles post requests
app.use(express.bodyParser());
//Handles put requests
app.use(express.methodOverride());

Ama yine req.body.somethingde rotalarımda istediğimde bunu gösteren bir hata alıyorum body is undefined. İşte kullanan bir rota örneğireq.body :

app.post('/admin', function(req, res){
    console.log(req.body.name);
});

Bu sorunun, app.use(express.bodyParser()); ama gördüğünüz gibi rotalardan önce çağırıyorum.

Bir ipucu?

Yanıtlar:


296

Güzergahları tanımlamadan ÖNCE tüm konfigürasyonları tanımladığınızdan emin olmalısınız. Bunu yaparsanız, kullanmaya devam edebilirsinizexpress.bodyParser() .

Bir örnek şöyledir:

var express = require('express'),
    app     = express(),
    port    = parseInt(process.env.PORT, 10) || 8080;

app.configure(function(){
  app.use(express.bodyParser());
  app.use(app.router);
});

app.listen(port);

app.post("/someRoute", function(req, res) {
  console.log(req.body);
  res.send({ status: 'SUCCESS' });
});

9
Bu benim için çalıştı. Not: Ne yazık ki, bazı öğreticiler app.configure () 'den önce rota koyan insanlar (benim gibi) var. Benim durumumda bu app.get / post vb ve onları içeren bir requir () biçimindeydi.
bendman

1
Çok teşekkürler, bütün gün bu sorunu gideriyorum.
jfplataroti

11
ifade 4'ten itibaren app.use (app.router) kaldırıldı. lütfen gitsub.com/visionmedia/express/wiki/New-features-in-4.x
Jonathan Ong

15
Express 4'ten itibaren, bodyParser gibi ara yazılımlar artık Express ile birlikte verilmez ve ayrıca kurulmalıdır. Daha fazla bilgiyi burada bulabilirsiniz: github.com/senchalabs/connect#middleware .
andrea.rinaldi

2
Teşekkürler. Bu cevap 2 yaşından büyük ve hala sorun yaşayan insanlara yardım ediyor :)
Lorenzo Marcon

275

Express'in (4.x) en son sürümleri ara katmanı çekirdek çerçeveden ayırmıştır. Gövde ayrıştırıcısına ihtiyacınız varsa, ayrı olarak yüklemeniz gerekir

npm install body-parser --save

ve bunu kodunuzda yapın

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

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

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

2
Geçenlerde 4.x ifade etmek için güncelledim. Başlangıçta req.body oturum açmaya çalışırken bana tanımsız gösteriyordu. Vücut ayrıştırıcısını kurup kullandığımda, bana beklenen req.body değerlerini veriyor. :)
Alok Adhao

POST isteklerimin neden json-server ile çalışmadığını anlamaya çalışırken bunu yararlı buldum.
freethebees

Günümü, özellikle 'app.use (bodyParser.json ())' bölümünü kurtardı. Sağ ol, kanka ! : D
neaGaze

Bu kabul edilen cevap olmalı çünkü Express 4 için tamamen işe yarıyor! Teşekkürler bayım!
birleştirin

2
app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()) beni kurtardı !!
Pramesh Bajracharya

71

Hayır. Daha app.use(express.bodyParser())önce kullanmanız gerekiyor app.use(app.router). Aslında, app.use(app.router)aradığınız son şey olmalı.


Çağrıların app.use(app.router)altında hareket etmek bile .usesorunu çözmüyor :(.
Masiar

Tamam, biraz uğraştıktan sonra app.use(require('connect').bodyParser());yerine kullanarak çözdüm app.use(express.bodyParser());.
Masiar

evet, cevap kullanırken bile doğrudur var router=express.Router();
Istiaque Ahmed

1
Hafif ek, hala uygulamadan sonra hata işleme ara yazılım çağırmalısınız. Yönlendirici
craft

BU YORUM SİYAH
Ke Ke

40

Öncelikle, 'body-parser' adlı npm modülünü arayarak kurduğunuzdan emin olun:

npm install body-parser --save

Ardından, rotaları aramadan önce aşağıdaki hatları eklediğinizden emin olun

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

app.use(bodyParser.json());

Express.json kullanıyorsa, neden body-parser içe aktarılsın?
SanSolo

38

Express 4, yerleşik vücut ayrıştırıcıya sahiptir. Ayrı bir vücut ayrıştırıcısı kurmaya gerek yoktur. Yani aşağıda çalışacak:

export const app = express();
app.use(express.json());

37

İstek başlığındaki İçerik Türü, özellikle verileri curl'den veya diğer araçlardan yüklediğinizde gerçekten önemlidir.

Application / x-www-form-urlencoded, application / json ya da diğerleri gibi bir şey kullandığınızdan emin olun, bu yazı verilerinize bağlıdır. Bu alanı boş bırakın Express karıştıracaktır.


12
+1 Benim için sorun buydu. REST'te yerleşik bir JSON api sınamak için Postman for Chrome kullanıyordum, ancak Express tarafından alınan nesne her seferinde boştu. Varsayılan olarak Postman'a dışarı dönüşler yok değil otomatik 'Content-Type: application / json' eklemek için başlığı ham seçseniz bile> json.
Ürdün

@Jordan +1 Bunu işaret ettiğiniz için teşekkürler. Gerçekten de sadece başlıklarımı kontrol ettim ve 'json' seçmiş olmama rağmen hala 'text / plain' olarak ayarlandığını görüyorum.
Mühendis

Ugh ... 7 yıl sonra ve bu hala beni harekete
geçiren

33

Zaten bir yorum altında yayınlandığı gibi, bunu kullanarak çözdüm

app.use(require('connect').bodyParser());

onun yerine

app.use(express.bodyParser());

Basit olanın neden express.bodyParser()çalışmadığını hala bilmiyorum ...


1
@Masiar Bu benim için çalışmıyor. expressjs 4 kullanıyorum & böyle hata alıyorum. Hata: 'connect' modülü bulunamıyor
Jeyarathnem Jeyachanthuru

1
@JeyTheva madeni oldukça eski bir çözüm, bu nedenle işler değişmiş olabilir. connectModülü üzerinden yüklemeyi npm install connectve tekrar denemenizi öneririm . Hatanızın çıktısını okuyarak aklıma gelen tek şey bu.
Masiar

4
İşte bu sorunu çözmek için en son belgeler: npmjs.com/package/body-parser Bu sorunu yaşayan diğerleri için "post express 4", benim için işe yarayanContent-Type başlığı ayarlamaktı application/json.
Grant Eagon

3
İşte bu sorunu çözmek için en son belgeler: npmjs.com/package/body-parser Vücut ayrıştırıcısı yüklendikten sonra hala çalışmadı. Yaptığım şey, isteğimi yaparken Content-Typeüstbilgiyi ayarlamaktı application/json.
Grant Eagon

1
application/jsonvs text/json, @GrantEagon tarafından önerildiği gibi, istek işlerinde.
strider

21
// Require body-parser (to receive post data from clients)

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

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

// parse application/json

app.use(bodyParser.json())

20

Ekleyin app.js

Yönlendiricinin çağrısından önce

const app = express();
app.use(express.json());

2
günümü kurtardın adamım! Anahtar, çağrı yönlendiricisinden önce hattı eklemek
ubaldisney

Bu şey beni kurtardı. Teşekkürler :)
Farrukh Faizy

12

Görünüşe göre, vücut ayrıştırıcısı artık ekspres ile gönderilmiyor. Ayrı olarak yüklememiz gerekebilir.

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

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

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

// parse application/vnd.api+json as json
app.use(bodyParser.json({ type: 'application/vnd.api+json' }))
app.use(function (req, res, next) {
console.log(req.body) // populated!

Daha fazla bilgi ve örnekler için git sayfasına bakınız https://github.com/expressjs/body-parser .


1
Bu yeni Express 4.x biçimi gibi görünüyor ve benim için çalıştı. Diğer yanıtlarda belirtilen express.bodyParser () yöntemi 4.x'te çalışmaz.
DustinB

10

Herkes aynı sorunla karşılaşırsa ben vardı; Gibi bir url öneki kullanıyorum

http://example.com/api/

hangi yönlendirici ile kuruldu

app.use('/api', router); 

ve sonra aşağıdakilere sahiptim

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

Sorunum düzeltildi, üstyapı denetleyicisi yapılandırmasını yukarıda app.use('/api', router);

final

// setup bodyparser
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));

//this is a fix for the prefix of example.com/api/ so we dont need to code the prefix in every route
    app.use('/api', router); 

9

express.bodyParser () 'a ne tür bir içerik ayrıştırıldığı söylenmelidir. Bu nedenle, bir POST isteği yürütürken "İçerik Türü" üstbilgisini eklediğinizden emin olmanız gerekir. Aksi takdirde, bodyParser POST isteğinizin gövdesi ile ne yapacağınızı bilemeyebilir.

Vücutta bazı JSON nesneleri içeren bir POST isteği yürütmek için curl kullanıyorsanız, şöyle bir şey olur:

curl -X POST -H "Content-Type: application/json" -d @your_json_file http://localhost:xxxx/someRoute

Başka bir yöntem kullanıyorsanız, uygun olan her konuyu kullanarak başlık alanını ayarladığınızdan emin olun.


8

App.use (bodyparser.json ()) kullanın ; yönlendirmeden önce. //. app.use ("/ api", rotalar);



7

Çoğu zaman req.body eksik JSON ayrıştırıcı nedeniyle tanımsız

const express = require('express');
app.use(express.json());

gövde ayrıştırıcı için eksik olabilir

const bodyParser  = require('body-parser');
app.use(bodyParser.urlencoded({extended: true}));

ve bazen cros kökeni nedeniyle tanımsızdır, bu yüzden onları ekleyin

const cors = require('cors');
app.use(cors())

5

Bu bana bugün oldu. Yukarıdaki çözümlerin hiçbiri benim için çalışmıyor. Ama biraz googling bu sorunu çözmeme yardımcı oldu. Wechat 3. parti sunucusu için kod yazıyorum.

Node.js uygulamanız bir REST istemcisinin isteği gibi akışlı POST verilerinin okunmasını gerektirdiğinde işler biraz daha karmaşık hale gelir. Bu durumda, isteğin "okunabilir" özelliği true değerine ayarlanır ve tüm içeriği toplamak için POST verilerinin parçalar halinde okunması gerekir.

http://www.primaryobjects.com/CMS/Article144


gönderide HTML formu gönderiminden REST İstemcisi isteğinden farklı olarak bahsediliyor. her ikisi de http isteği değil mi? Peki, akış gerektiren tek durum POST?
j10

5

Çok zaman harcadım:

İstemci isteğinizdeki İçerik Türü'ne bağlı olarak
, sunucunun farklı olması gerekir, aşağıdaki app.use () yönteminden biri:

app.use(bodyParser.text({ type: 'text/html' }))
app.use(bodyParser.text({ type: 'text/xml' }))
app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }))
app.use(bodyParser.json({ type: 'application/*+json' }))

Kaynak: https://www.npmjs.com/package/body-parser#bodyparsertextoptions

Misal:

Benim için, Müşteri tarafında, başlığın altındaydım:

Content-Type: "text/xml"

Yani sunucu tarafında kullandım:

app.use(bodyParser.text({type: 'text/xml'}));

Sonra, req.body iyi çalıştı.


5

Express 4'te, gerçekten basit

const app = express()
const p = process.env.PORT || 8082

app.use(express.json()) 

4

Çalışmak için app.use (express.bodyParser ()) uygulamasından sonra app.use (app.router) uygulamasını kullanmanız gerekir:

app.use(express.bodyParser())
   .use(express.methodOverride())
   .use(app.router);

1
Yorumunuz ve kod snippet'iniz çelişkilidir. Öncelikle daha önce kullanmanız gerektiğini söylüyorsunuz app.use, ancak kodunuz açıkça SONRA olduğunu gösteriyor. Peki hangisi? app.routerexpress.bodyParser
Levi Roberts

1
Üzgünüm dostum. Express.bodyParser öğesinden sonra app.router kullanmanız gerekir.
HenioJR

1
@LeviRoberts
HenioJR

4
var bodyParser = require('body-parser');
app.use(bodyParser.json());

Bu benim günümü kurtardı.


4

Bu sorun, gövde ayrıştırıcısını kullanmamanızdan kaynaklanabilir ( bağlantı )

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

var app = express();
app.use(bodyParser.json());

3

Ben çözdüm:

app.post('/', bodyParser.json(), (req, res) => {//we have req.body JSON
});

3

Bu da bir olasılıktır : Bu kodu app.js (veya index.js) dosyanızdaki rotadan önce yazdığınızdan emin olun.

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

2

Ekspres gövde ayrıştırıcısını kullanabilirsiniz.

var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));

2

Express'in son sürümünde zaten gövde ayrıştırıcı yerleşiktir. Böylece şunları kullanabilirsiniz:

const express = require('express);
... 
app.use(express.urlencoded({ extended: false }))
.use(express.json());

1

SOAP mesajı gönderiyorsanız, ham gövde ayrıştırıcı kullanmanız gerekir:

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

app.use(bodyParser.raw({ type: 'text/xml' }));

1

@ Kevin-xue üzerine kurulduğunda, içerik türünün bildirilmesi gerekiyor. Benim durumumda, bu yalnızca IE9 ile gerçekleşiyordu çünkü XDomainRequest bir içerik türü ayarlamıyordu, bu nedenle bodyparser ve expressjs isteğin gövdesini yok sayıyordu.

Bu gibi vücut ayrıştırıcısı üzerinden isteği geçmeden önce içerik türü açıkça ayarlayarak bu var:

app.use(function(req, res, next) {
    // IE9 doesn't set headers for cross-domain ajax requests
    if(typeof(req.headers['content-type']) === 'undefined'){
        req.headers['content-type'] = "application/json; charset=UTF-8";
    }
    next();
})
.use(bodyParser.json());

1

Harika cevap için @spikeyang'a teşekkür edin (aşağıda verilmiştir). Gönderiye ekli önerilen makaleyi okuduktan sonra çözümümü paylaşmaya karar verdim.

Ne zaman kullanılır?

Çözüm, hızlı yönlendiricinin keyfini çıkarmak için kullanmanızı gerektiriyordu. Öyleyse: Kabul edilen yanıtı şanssız kullanmaya çalıştıysanız, bu işlevi kopyalayıp yapıştırın:

function bodyParse(req, ready, fail) 
{
    var length = req.header('Content-Length');

    if (!req.readable) return fail('failed to read request');

    if (!length) return fail('request must include a valid `Content-Length` header');

    if (length > 1000) return fail('this request is too big'); // you can replace 1000 with any other value as desired

    var body = ''; // for large payloads - please use an array buffer (see note below)

    req.on('data', function (data) 
    {
        body += data; 
    });

    req.on('end', function () 
    {
        ready(body);
    });
}

ve şöyle deyin:

bodyParse(req, function success(body)
{

}, function error(message)
{

});

NOT: Büyük yükler için - lütfen bir dizi arabelleği kullanın ( more @ MDN )


bodyParser paketi yaygın olarak kullanılır ve yükü bir gövde nesnesine çevirir. diğer cevaplarda belirtildiği gibi
Schuere

1

İstekte bulunmak için harici bir araç kullanıyorsanız, başlığı eklediğinizden emin olun:

Content-Type: application/json


Bu bana yardımcı oldu, Postacı ile çalışıyordum, teşekkürler dostum.
R. Gurung

1

Yukarıdaki cevapların hiçbirinin işe yaramadığı herkes için ön uç ve ekspres arasındaki cors'ı etkinleştirmem gerekiyordu.

Bunu şu şekilde yapabilirsiniz:

  1. Tarayıcınız için aşağıdakiler gibi bir CORS uzantısını indirme ve açma:

    https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en

    Chrome için,

veya tarafından

  1. Satır ekleme

    var cors=require('cors');
    
    app.use(cors());

hızlı app.jssayfanıza. (Sonra npm install cors)

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.