req.body kosong di pos

256

Tiba-tiba ini terjadi pada semua proyek saya.

Setiap kali saya membuat posting di nodejs menggunakan express dan body-parser req.bodyadalah objek kosong.

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

Melalui ajax dan tukang pos itu selalu kosong.

Namun via ikal

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

itu berfungsi sebagaimana dimaksud.

Saya mencoba pengaturan secara manual Content-type : application/jsondi yang pertama tetapi kemudian saya selalu mendapatkannya400 bad request

Ini membuatku gila.

Saya pikir itu sesuatu yang diperbarui di body-parser tapi saya menurunkannya dan itu tidak membantu.

Bantuan apa pun dihargai, terima kasih.

Joseph Dailey
sumber
16
Jadi, Anda mencoba mengatur secara eksplisit Content-Typetukang pos? Jika tidak, Anda dapat mencobanya, karena saya pernah mengalami masalah dengan tukang pos yang tidak mengirim Content-Type.
mscdex
ya saya lakukan. saat itulah saya menerima 400: json tidak valid
Joseph Dailey
@mscdex - terima kasih saya tidak mengatur konten-tupe di tukang pos dan menjadi gila :)
Muzafar Ali
Bagi orang-orang yang datang ke sini karena mereka ingin mengirim / mengunggah file dari API mereka dan karenanya harus menggunakan formulir-data. Anda memerlukan sesuatu untuk menangani data formulir: npmjs.com/package/multer adalah paket yang cukup populer.
bhaskar
Tidak peduli apa pun, tukang pos tidak berurusan dengan bilangan bulat dan nilai float dengan sangat baik. Jika Anda memiliki nilai integer atau float, pastikan untuk menggandakan semuanya, baik kunci dan nilai
anabeto93

Jawaban:

272

Dalam tukang pos dari 3 opsi yang tersedia untuk jenis konten pilih "X-www-form-urlencoded" dan itu akan berfungsi.

Juga untuk menyingkirkan pesan kesalahan ganti:

app.use(bodyParser.urlencoded())

Dengan:

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

Lihat https://github.com/expressjs/body-parser

Middleware 'body-parser' hanya menangani JSON dan data urlencoded, bukan multipart

Mick Cullen
sumber
Itu bekerja untuk tukang pos, saya tidak yakin mengapa itu bekerja dengan ajax karena saya tidak mengubah apa pun.
Joseph Dailey
Untuk beberapa alasan, posting http melalui Angular tidak perlu disandikan URL, tetapi panggilan ajax melakukannya. Adakah yang tahu kenapa?
youngrrrr
Ini bekerja untuk saya, mengapa tidak bekerja dengan mentah dikodekan?
Daniel Kobe
9
sekarang body-parser inbuilt dengan express.js gunakan sajaapp.use(express.json());
Sujeet Agrahari
Terima kasih banyak! Meski sudah lama dijawab, tetap relevan.
Spray'n'Pray
218

Dengan tukang pos, untuk menguji tindakan posting HTTP dengan muatan data JSON mentah, pilih rawopsi dan atur parameter header berikut:

Content-Type: application/json

Juga, pastikan untuk membungkus string apa pun yang digunakan sebagai kunci / nilai dalam muatan JSON Anda dalam tanda kutip ganda.

The body-parserpaket akan mengurai multisaluran muatan JSON baku baik-baik saja.

{
    "foo": "bar"
}

Diuji di Chrome v37 dan v41 dengan ekstensi Postman v0.8.4.13 ( body-parserv1.12.2 dan expressv4.12.3) dengan penyiapan di bawah ini:

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

Tukang pos mentah muatan json

sirthud
sumber
Ya ampun, bagaimana saya bisa melewatkan bahwa saya menempelkan objek JS literal daripada objek JSON yang diformat dengan benar ...: -S ... terima kasih teman!
Wes Johnson
Membungkus string apa pun yang digunakan sebagai kunci / nilai dalam tanda kutip ganda ... Mudah dilewatkan tetapi sebagai pemecah kesepakatan total sebaliknya! Terima kasih.
loxyboi
Penggunaan screenshot yang bagus.
Xan-Kun Clark-Davis
Saat digunakan form-datadi tukang pos untuk mengirim data, saya selalu mendapatkan {}di req.body. Haruskah saya mengatur Content-Typeopsi?
mingchau
56

Saya membuat kesalahan yang sangat bodoh dan lupa mendefinisikan nameatribut untuk input dalam file html saya.

Jadi, bukannya

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

Aku punya ini.

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

Sekarang request.bodydiisi seperti ini:{ password: 'hhiiii' }

Jason Kim
sumber
1
Bam. Itu masalahnya. Terima kasih!
Matt West
Itulah masalah saya, input formulir tanpa nilai nama, menghabiskan waktu berjam-jam untuk mencari tahu. Terima kasih.
karensantana
37

Saya menemukan, bahwa itu berfungsi ketika mengirim dengan tipe konten

"aplikasi / json"

dalam kombinasi dengan sisi server

app.use(bodyParser.json());

Sekarang saya dapat mengirim via

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

dan hasilnya tersedia di request.body.nameserver.

Xan-Kun Clark-Davis
sumber
Terima kasih atas upvotenya. Saya benar-benar berpikir ini adalah yang terbersih, meskipun bukan solusi paling sederhana, karena Anda harus mengirim tipe konten yang benar. Kupikir.
Xan-Kun Clark-Davis
ini jawabannya!
Gel
Dalam kasus saya, saya harus mengubahnya kexmlHttp.send(JSON.stringify(data));
endo64
18

Saya mengalami masalah ini hari ini, dan apa yang diperbaiki adalah menghapus header tipe konten di Postman! Sangat aneh. Menambahkannya di sini kalau-kalau itu membantu seseorang.

Saya mengikuti tutorial BeerLocker di sini: http://scottksmith.com/blog/2014/05/29/beer-locker-building-a-restful-api-with-node-passport/

batu
sumber
2
Saya memiliki masalah yang sama. memiliki tajuk "tidak dicentang" (dan diklik) tidak cukup, saya harus menghapusnya sepenuhnya. meskipun tombol sumber "</>" menunjukkan bahwa saya tidak mengirim tajuk itu dengan Tipe-Konten berada dalam keadaan tidak dicentang, masih perlu dihapus sepenuhnya.
theRemix
Saya tidak tahu cara menghapus header default di ekstensi chrome tukang pos ... apakah Anda menggunakan aplikasi mungkin?
WestleyArgentum
Oh, saya menginstal aplikasi dan berfungsi lebih baik daripada ekstensi. Maaf atas kebisingannya.
WestleyArgentum
12

Anda harus memeriksa apakah middleware body-parser diatur dengan benar untuk jenis permintaan (json, urlencoded).

Jika sudah diatur,

app.use(bodyParser.json());

maka pada tukang pos Anda harus mengirim data sebagai mentah.

https://i.stack.imgur.com/k9IdQ.png tangkapan layar tukang pos

Jika sudah diatur,

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

maka opsi 'x-www-form-urlencoded' harus dipilih.

Tuan
sumber
bagaimana dengan memiliki keduanya? (bodyParser.urlencoded dan bodyParser.json ()) ... mana yang bisa saya gunakan di tukang pos?
TommyLeong
9

Masalah saya adalah saya membuat rute terlebih dahulu

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

dan mendaftarkan middleware setelah rute

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

karena struktur aplikasi & salin dan tempel proyek bersama-sama dari contoh.

Setelah saya memperbaiki pesanan untuk mendaftar middleware sebelum rute, semuanya berhasil.

perintah
sumber
terima kasih fiat, dengan urutan yang benar dan menggunakan tab baku, akhirnya berhasil bagi saya
Alex
4

Bahkan ketika saya sedang belajar node.js untuk pertama kalinya di mana saya mulai mempelajarinya melalui web-app, saya telah melakukan semua hal ini dengan baik dalam formulir saya, masih saya tidak dapat menerima nilai dalam permintaan posting. Setelah lama debugging, saya mengetahui bahwa dalam bentuk yang saya berikan enctype="multipart/form-data"karena saya tidak bisa mendapatkan nilai. Saya hanya menghapusnya dan itu berhasil untuk saya.

Shaggie
sumber
ya, ini juga berfungsi untuk mendapatkan tubuh formulir tetapi kemudian menyebabkan masalah lain dengan formulir saya - pada dasarnya file tidak dapat diunggah karena memerlukan inienctype="multipart/form-data"
tsando
btw, hanya untuk menambahkan komentar saya di atas, saya berhasil mendapatkan ini bekerja multer- lihat dokumentasi di npmjs.com/package/multer
tsando
3

Tampaknya jika Anda tidak menggunakan encType apa pun (standarnya adalah application/x-www-form-urlencoded) maka Anda mendapatkan bidang input teks tetapi Anda tidak akan mendapatkan file.

Jika Anda memiliki formulir di mana Anda ingin memposting input teks dan file kemudian gunakan multipart/form-datajenis penyandian dan selain itu menggunakan multermiddleware. Multer akan menguraikan objek permintaan dan mempersiapkan req.fileuntuk Anda dan semua bidang input lainnya akan tersedia melalui req.body.

Mohammad Haque
sumber
1
terima kasih - multermemang solusi untuk masalah saya. Akan lebih baik jika Anda dapat menambahkan contoh tentang bagaimana menggunakan ini sebagai bagian dari jawaban Anda
tsando
2

Masalah serupa terjadi pada saya, saya hanya mencampur urutan parade callback. Pastikan Anda mengatur fungsi panggilan balik dalam urutan yang benar. Setidaknya bagi siapa pun yang memiliki masalah yang sama.

router.post('/', function(req, res){});
Henry Ollarves
sumber
2

Pastikan ["kunci": "ketik", "nilai": "json"] & ["kunci": "Jenis-Konten", "nilai": "application / x-www-form-urlencoded"] ada di Anda tajuk permintaan tukang pos

vpage
sumber
2

Saya memecahkan ini menggunakan multerseperti yang disarankan di atas, tetapi mereka tidak memberikan contoh yang berfungsi penuh, tentang bagaimana melakukan ini. Pada dasarnya ini bisa terjadi ketika Anda memiliki grup formulir enctype="multipart/form-data". Ini HTML untuk formulir yang saya punya:

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

Dan inilah cara menggunakannya multeruntuk mendapatkan nilai dan nama formulir ini dengan Express.jsdan 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)
});
tsando
sumber
1

Saya memiliki masalah yang sama beberapa menit yang lalu, saya mencoba segala kemungkinan dalam jawaban di atas tetapi ada yang berhasil.

Satu-satunya hal yang saya lakukan, adalah meng-upgrade versi Node JS, saya tidak tahu bahwa peningkatan dapat memengaruhi sesuatu, tetapi itu benar.

Saya telah menginstal versi Node JS 10.15.0( versi terbaru), saya kembali ke 8.11.3dan semuanya sekarang berfungsi. Mungkin body-parsermodul harus memperbaikinya.

Phi
sumber
1

Saya tidak memiliki nama di Input saya ... permintaan saya kosong ... senang itu sudah selesai dan saya bisa terus coding. Terimakasih semuanya!

Jawaban yang saya gunakan oleh Jason Kim:

Jadi, bukannya

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

aku punya ini

<input type="password" class="form-control" id="password" name="password">
Luke McCormick
sumber
1

Anda tidak boleh melakukannya JSON.stringify(data)saat mengirim melalui AJAX seperti di bawah ini.

Ini BUKAN kode yang benar:

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

Kode yang benar adalah:

function callAjax(url, data) {
    $.ajax({
        url: url,
        type: "POST",
        data: data,
        success: function(d) {
            alert("successs "+ JSON.stringify(d));
        }
    });
}
Achilles Ram Nakirekanti
sumber
satu hal penting yang perlu diperhatikan di sini adalah dalam jenis, pastikan Anda menggunakan huruf besar "POST". Saya telah melihat contoh di mana hanya menggunakan "posting" telah menyebabkan blank req.body.
Matt C.
1

Jika Anda melakukannya dengan tukang pos, Harap konfirmasikan hal-hal ini ketika Anda meminta API

masukkan deskripsi gambar di sini

vignesh
sumber
0

Saya menggunakan restify bukannya express dan mengalami masalah yang sama. Solusinya adalah melakukan:

server.use(restify.bodyParser());
Prabhat
sumber
0

Saya yakin ini bisa menyelesaikannya app.use(express.json());

Cleber Carvalho
sumber
0

Ubah app.use(bodyParser.urlencoded());kode Anda menjadi

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

dan di tukang pos, di header perubahan Content-Typenilai dari application/x-www-form-urlencodedmenjadiapplication/json

Ta :-)

Abhijith Brumal
sumber
0

Terima kasih atas jawaban Anda! Menghabiskan waktu mencari solusi, dan di sisi saya, saya membuat kesalahan mendasar: Saya menelepon bodyParser.json()dari dalam fungsi:

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

Saya hanya perlu melakukan app.use(['/password'], bodyParser.json())dan itu berhasil ...

musiquarc
sumber
0

Di tukang pos, bahkan setelah mengikuti jawaban yang diterima, saya mendapatkan tubuh permintaan kosong. Masalahnya ternyata tidak melewati tajuk yang disebut

Content-Length : <calculated when request is sent>

Header ini hadir secara default (bersama 5 lainnya) yang telah saya nonaktifkan. Aktifkan ini dan Anda akan menerima badan permintaan.

kaushalpranav
sumber
0

Masalah saya adalah membuat rute terlebih dahulu require("./routes/routes")(app); saya menggesernya ke akhir kode sebelum app.listen dan berhasil!

Tushar Kudal
sumber