Express.js req.body tidak terdefinisi

291

Saya memiliki ini sebagai konfigurasi server Express saya

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

Tapi tetap ketika saya meminta req.body.somethingrute saya, saya mendapatkan beberapa kesalahan menunjukkan itu body is undefined. Berikut adalah contoh rute yang menggunakan req.body:

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

Saya membaca bahwa masalah ini disebabkan oleh kurangnya app.use(express.bodyParser());tetapi seperti yang Anda lihat saya menyebutnya sebelum rute.

Ada petunjuk?

Masiar
sumber

Jawaban:

296

Anda harus memastikan bahwa Anda mendefinisikan semua konfigurasi SEBELUM menentukan rute. Jika Anda melakukannya, Anda dapat terus menggunakan express.bodyParser().

Contohnya adalah sebagai berikut:

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' });
});
Mark Bonano
sumber
9
Ini berhasil untuk saya. Catatan: Sayangnya, beberapa tutorial di luar sana memiliki orang-orang (seperti saya) yang menempatkan rute sebelum app.configure (). Dalam kasus saya ini adalah dalam bentuk app.get / post dll, dan memerlukan () termasuk mereka.
bendman
1
Terima kasih banyak, saya telah memecahkan masalah ini sepanjang hari.
jfplataroti
11
pada express 4, app.use (app.router) dihapus. silakan lihat dokumen github.com/visionmedia/express/wiki/New-features-in-4.x
Jonathan Ong
15
pada express 4, middlewares seperti bodyParser tidak lagi dibundel dengan Express dan harus diinstal secara terpisah. Anda dapat menemukan informasi lebih lanjut di sini: github.com/senchalabs/connect#middleware .
andrea.rinaldi
2
Terima kasih. Jawaban ini lebih dari 2 tahun dan masih terus membantu orang dalam kesulitan :)
Lorenzo Marcon
275

Versi Express terbaru (4.x) telah membatalkan ikatan middleware dari kerangka inti. Jika Anda membutuhkan pengurai tubuh, Anda harus menginstalnya secara terpisah

npm install body-parser --save

dan kemudian lakukan ini dalam kode Anda

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())
Jay
sumber
2
Saya baru-baru ini diperbarui untuk mengekspresikan 4.x. Awalnya ketika saya mencoba login req.body Itu menunjukkan saya tidak terdefinisi. Setelah saya menginstal dan menggunakan body-parser, itu memberi saya nilai req.body yang diharapkan. :)
Alok Adhao
Saya menemukan ini berguna ketika mencoba mencari tahu mengapa permintaan POST saya tidak berfungsi dengan json-server.
freethebees
Menyimpan hari saya, terutama bagian 'app.use (bodyParser.json ())'. Terima kasih kawan! : D
neaGaze
Ini harus menjadi jawaban yang diterima karena ini benar-benar berfungsi untuk Express 4! Terima kasih Pak!
Gabungkan
2
app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()) menyelamatkan saya !!
Pramesh Bajracharya
71

Tidak. Anda harus menggunakan app.use(express.bodyParser())sebelumnya app.use(app.router). Padahal, app.use(app.router)seharusnya menjadi hal terakhir yang Anda telepon.

danmactough
sumber
Bahkan bergerak di app.use(app.router)bawah .usepanggilan tidak menyelesaikan masalah :(.
Masiar
Ok setelah sedikit berjuang saya menyelesaikannya menggunakan app.use(require('connect').bodyParser());bukan app.use(express.bodyParser());.
Masiar
ya, jawaban itu benar bahkan ketika menggunakan var router=express.Router();
Istiaque Ahmed
1
Sedikit tambahan, Anda masih harus memanggil middleware penanganan kesalahan setelah app.router
craft
KATAKAN KOMENTAR INI
Ke Ke
40

Pertama pastikan, Anda telah menginstal modul npm bernama 'body-parser' dengan menelepon:

npm install body-parser --save

Kemudian pastikan Anda telah memasukkan baris berikut sebelum memanggil rute

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

app.use(bodyParser.json());
Ankit kaushik
sumber
Jika menggunakan express.json, lalu mengapa mengimpor body-parser?
SanSolo
38

Express 4, memiliki pengurai tubuh bawaan. Tidak perlu menginstal body-parser yang terpisah. Jadi di bawah ini akan berfungsi:

export const app = express();
app.use(express.json());
TechTurtle
sumber
37

Content-Type dalam header permintaan sangat penting, terutama ketika Anda memposting data dari curl atau alat lain.

Pastikan Anda menggunakan sesuatu seperti application / x-www-form-urlencoded, application / json atau yang lainnya, itu tergantung pada data posting Anda. Biarkan bidang ini kosong akan membingungkan Express.

Kevin Xue
sumber
12
+1 Ini adalah masalah bagi saya. Saya menggunakan tukang pos untuk Chrome untuk menguji api JSON yang dibangun di REST, tetapi objek yang diterima oleh Express kosong setiap kali. Ternyata tukang pos secara default tidak secara otomatis menambahkan header 'Tipe Konten: aplikasi / json' bahkan jika Anda memilih mentah> json.
Jordan
@Jordan +1 Terima kasih telah menunjukkan ini. Memang saya baru saja memeriksa header saya dan saya melihat itu masih diatur ke 'text / plain' walaupun saya memilih 'json'.
Insinyur
Ugh ... 7 tahun kemudian dan ini masih membuatku tersandung ...
Shaun314
33

Seperti yang sudah diposting di bawah satu komentar, saya menyelesaikannya menggunakan

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

dari pada

app.use(express.bodyParser());

Saya masih tidak tahu mengapa yang sederhana express.bodyParser()tidak berfungsi ...

Masiar
sumber
1
@Masiar Ini tidak berfungsi untuk saya. Saya menggunakan expressjs 4 & saya mendapatkan kesalahan seperti ini. Kesalahan: Tidak dapat menemukan modul 'terhubung'
Jeyarathnem Jeyachanthuru
1
@JeyTheva menambang adalah solusi yang cukup lama, sehingga hal-hal dapat berubah dalam waktu yang bersamaan Saya sarankan Anda mencoba menginstal connectmodul via npm install connectdan coba lagi. Ini adalah satu-satunya hal yang dapat saya pikirkan dengan membaca output dari kesalahan Anda.
Masiar
4
Berikut dokumentasi terbaru untuk menyelesaikan masalah ini: npmjs.com/package/body-parser Bagi yang lain yang mengalami masalah ini "post express 4", yang berhasil bagi saya adalah mengatur Content-Typetajuk application/json.
Grant Eagon
3
Berikut dokumentasi terbaru untuk menyelesaikan masalah ini: npmjs.com/package/body-parser Setelah menginstal body-parser, itu masih tidak berfungsi. Apa yang berhasil adalah mengatur Content-Typetajuk application/jsonketika saya melakukan permintaan saya.
Grant Eagon
1
application/jsonvs text/jsondalam permintaan berfungsi, seperti yang disarankan oleh @GrantEagon.
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())
ASHISH RANJAN
sumber
20

Tambahkan di app.js

sebelum panggilan Router

const app = express();
app.use(express.json());
abdesselam
sumber
2
Anda menyelamatkan manusia hari saya! Kuncinya adalah tambahkan baris sebelum router panggilan
ubaldisney
Hal ini menyelamatkan saya. Terima kasih :)
Farrukh Faizy
12

Sepertinya body-parser tidak lagi dikirim dengan express. Kami mungkin harus menginstalnya secara terpisah.

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!

Lihat halaman git https://github.com/expressjs/body-parser untuk info dan contoh lebih lanjut.

Praneesh
sumber
1
Tampaknya ini format Express 4.x baru dan berfungsi untuk saya. Express.bodyParser () yang disebutkan dalam jawaban lain tidak berfungsi di 4.x.
DustinB
10

Seandainya ada orang yang mengalami masalah yang sama dengan yang saya alami; Saya menggunakan awalan url seperti

http://example.com/api/

yang diatur dengan router

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

dan kemudian saya memiliki yang berikut

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

Apa yang memperbaiki masalah saya adalah menempatkan konfigurasi bodyparser di atas app.use('/api', router);

Terakhir

// 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); 
Jeff Beagley
sumber
9

express.bodyParser () perlu diberi tahu jenis konten apa yang diuraikan. Oleh karena itu, Anda perlu memastikan bahwa ketika Anda menjalankan permintaan POST, bahwa Anda termasuk header "Tipe Konten". Jika tidak, bodyParser mungkin tidak tahu apa yang harus dilakukan dengan isi permintaan POST Anda.

Jika Anda menggunakan ikal untuk menjalankan permintaan POST yang berisi beberapa objek JSON di dalam tubuh, itu akan terlihat seperti ini:

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

Jika menggunakan metode lain, pastikan untuk mengatur bidang header itu menggunakan konvensi apa pun yang sesuai.

ab107
sumber
8

Gunakan app.use (bodyparser.json ()); sebelum routing. //. app.use ("/ api", rute);

pengguna1614168
sumber
7

Anda dapat mencoba menambahkan baris kode ini di bagian atas, (setelah Anda memerlukan pernyataan):

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

Adapun alasan mengapa itu bekerja, periksa dokumen: https://www.npmjs.com/package/body-parser#bodyparserurlencodedoptions

Anthony Cantellano
sumber
Maksud saya, jawaban Anda benar, tetapi tidak ada bedanya dengan yang lain.
dwjohnston
7

Sebagian besar waktu req.body tidak terdefinisi karena parser JSON hilang

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

bisa hilang untuk parser tubuh

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

dan kadang-kadang itu tidak ditentukan karena asal silang jadi tambahkan mereka

const cors = require('cors');
app.use(cors())
raja neo
sumber
5

Ini terjadi pada saya hari ini. Tidak ada solusi di atas yang berfungsi untuk saya. Tapi sedikit googling membantu saya untuk menyelesaikan masalah ini. Saya sedang mengkode untuk server pihak ketiga WeChat.

Hal-hal menjadi sedikit lebih rumit ketika aplikasi node.js Anda perlu membaca streaming data POST, seperti permintaan dari klien REST. Dalam hal ini, properti permintaan "dapat dibaca" akan disetel ke true dan data POST harus dibaca dalam potongan untuk mengumpulkan semua konten.

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

spikeyang
sumber
posting menyebutkan pengiriman formulir HTML berbeda dari permintaan Klien REST. bukan keduanya permintaan http? jadi, POST adalah satu-satunya kasus yang membutuhkan streaming?
j10
5

Banyak waktu terbuang:

Tergantung pada Content-Type di Anda klien permintaan
tersebut server yang harus memiliki yang berbeda, salah satu di bawah ini app.use ():

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

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

Contoh:

Bagi saya, Di sisi Klien, saya memiliki header di bawah ini:

Content-Type: "text/xml"

Jadi, di sisi server, saya menggunakan:

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

Kemudian, req.body bekerja dengan baik.

Manohar Reddy Poreddy
sumber
5

di Express 4, ini sangat sederhana

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

app.use(express.json()) 
Gerardo Bautista
sumber
4

Agar berfungsi, Anda perlu app.use (app.router) setelah app.use (express.bodyParser ()) , seperti itu:

app.use(express.bodyParser())
   .use(express.methodOverride())
   .use(app.router);
HenioJR
sumber
1
Komentar dan cuplikan kode Anda saling bertentangan. Pertama, Anda mengatakan Anda harus menggunakan app.usepada app.routersebelum express.bodyParsertapi kode Anda jelas menunjukkan SETELAH itu. Jadi yang mana?
Levi Roberts
1
Maaf teman. Anda perlu menggunakan app.router setelah express.bodyParser.
HenioJR
1
Terima kasih @LeviRoberts
HenioJR
4
var bodyParser = require('body-parser');
app.use(bodyParser.json());

Ini menyelamatkan hari saya.

isdot
sumber
4

Masalah ini mungkin karena Anda belum menggunakan body-parser ( tautan )

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

var app = express();
app.use(bodyParser.json());
Arindam
sumber
3

Saya menyelesaikannya dengan:

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

Ini juga satu kemungkinan : Pastikan Anda harus menulis kode ini sebelum rute di file app.js (atau index.js) Anda.

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
Inamur Rahman
sumber
2

Anda dapat menggunakan pengurai tubuh ekspres.

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

Versi Express terbaru sudah memiliki body-parser built-in. Jadi Anda bisa menggunakan:

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

Jika Anda mengirim pesan SOAP, Anda perlu menggunakan pengurai tubuh mentah:

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

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

Membangun @ kevin-xue berkata, tipe konten perlu dideklarasikan. Dalam contoh saya, ini hanya terjadi dengan IE9 karena XDomainRequest tidak menetapkan tipe konten , jadi bodyparser dan expressjs mengabaikan tubuh permintaan.

Saya menyiasatinya dengan mengatur tipe-konten secara eksplisit sebelum meneruskan permintaan ke body parser, seperti:

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());
purpletonic
sumber
1

Kredit ke @spikeyang untuk jawaban yang bagus (disediakan di bawah). Setelah membaca artikel yang disarankan di pos, saya memutuskan untuk membagikan solusi saya.

Kapan harus menggunakan?

Solusi ini mengharuskan Anda untuk menggunakan router ekspres untuk menikmatinya .. jadi: Jika Anda sudah mencoba menggunakan jawaban yang diterima tanpa hasil, cukup gunakan fungsi salin dan tempel fungsi ini:

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

dan menyebutnya seperti:

bodyParse(req, function success(body)
{

}, function error(message)
{

});

CATATAN: Untuk muatan besar - silakan gunakan buffer array ( selengkapnya @ MDN )

ymz
sumber
paket bodyParser biasanya digunakan dan menerjemahkan muatan ke objek tubuh. seperti yang disediakan dalam jawaban lain
Schuere
1

Jika Anda menggunakan beberapa alat eksternal untuk membuat permintaan, pastikan untuk menambahkan header:

Content-Type: application/json

Termasuk33
sumber
Yang ini membantu saya, saya bekerja dengan tukang pos, terima kasih sobat.
R. Gurung