Bagaimana cara mengakses badan permintaan ketika POSTing menggunakan Node.js dan Express?

175

Saya memiliki kode Node.js berikut:

var express = require('express');
var app = express.createServer(express.logger());
app.use(express.bodyParser());

app.post('/', function(request, response) {
    response.write(request.body.user);
    response.end();
});

Sekarang jika saya POST sesuatu seperti:

curl -d user=Someone -H Accept:application/json --url http://localhost:5000

Saya mendapatkan Someoneseperti yang diharapkan. Sekarang, bagaimana jika saya ingin mendapatkan badan permintaan penuh? Saya mencoba melakukan response.write(request.body)tetapi Node.js melempar pengecualian yang mengatakan " argumen pertama harus berupa string atau Buffer " kemudian pergi ke "loop tak terbatas" dengan pengecualian yang mengatakan " Tidak dapat mengatur header setelah dikirim. "; ini juga berlaku bahkan jika saya melakukannya var reqBody = request.body;dan kemudian menulis response.write(reqBody).

Apa masalahnya di sini?

Juga, bisakah saya mendapatkan permintaan mentah tanpa menggunakan express.bodyParser()?

TheBlueSky
sumber
Tampaknya ada sesuatu dengan response.write(reqBody); ketika saya menggunakan response.send(reqBody)hal-hal bekerja dengan baik ... dan ya, saya gunakan response.endsetelah response.write.
TheBlueSky

Jawaban:

161

Express 4.0 dan di atas:

$ npm install --save body-parser

Dan kemudian di aplikasi simpul Anda:

const bodyParser = require('body-parser');
app.use(bodyParser);

Express 3.0 dan di bawah ini:

Coba sampaikan ini dalam panggilan CURL Anda:

--header "Content-Type: application/json"

dan memastikan data Anda dalam format JSON:

{"user":"someone"}

Juga, Anda bisa menggunakan console.dir dalam kode node.js Anda untuk melihat data di dalam objek seperti dalam contoh berikut:

var express = require('express');
var app = express.createServer();

app.use(express.bodyParser());

app.post('/', function(req, res){
    console.dir(req.body);
    res.send("test");
}); 

app.listen(3000);

Pertanyaan lain ini mungkin juga membantu: Bagaimana cara menerima JSON dalam permintaan POST node.js express?

Jika Anda tidak ingin menggunakan bodyParser lihat pertanyaan lain ini: https://stackoverflow.com/a/9920700/446681

Hector Correa
sumber
Saya mencoba menggunakan curl -d {"user":"Someone"} -H "Content-Type: application/json" --url http://localhost:5000tetapi itu memberi saya kesalahan " Token tak terduga ", itulah sebabnya saya beralih ke panggilan yang disebutkan di pos asli saya.
TheBlueSky
Saya menandai ini sebagai jawaban karena tautan stackoverflow.com/a/9920700/446681
TheBlueSky
40
express.bodyParser()tidak digunakan lagi dalam Express 4.x. Gunakan npmjs.org/package/body-parser sebagai gantinya.
Luc
@TheBlueSky alasan mengapa Anda mendapat "Token yang tidak terduga" adalah karena shell mengkonsumsi tanda kutip ganda Anda. Hal yang sama terjadi jika Anda melakukannya echo any"thing". Data yang Anda poskan harus dalam tanda kutip untuk mencegah hal ini terjadi.
Tom Fenech
11
Dari express 4.16.0 atau lebih tinggi, dimungkinkan untuk menggunakan express.json () di app.use () dengan cara ini => app.use (express.json ());
Mitro
187

Mulai dari express v4.16 tidak perlu memerlukan modul tambahan, cukup gunakan middleware JSON bawaan :

app.use(express.json())

Seperti ini:

const express = require('express')

app.use(express.json())    // <==== parse request body as JSON

app.listen(8080)

app.post('/test', (req, res) => {
  res.json({requestBody: req.body})  // <==== req.body will be a parsed JSON object
})

Catatan - body-parser, di mana ini tergantung, sudah termasuk dengan express.

Juga jangan lupa untuk mengirim tajuk Content-Type: application/json

rustyx
sumber
14
Terima kasih, ini adalah jawaban terbaik untuk 4.16+. Tidak ada dependensi lain dan bekerja seperti pesona!
codepleb
1
Solusi terbaik / satu-satunya yang bisa saya temukan yang tidak memerlukan pengurai tubuh
Mote Zart
41

Pada Express 4, kode berikut ini muncul untuk melakukan trik. Perhatikan bahwa Anda harus menginstal body-parsermenggunakan npm.

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


app.listen(8888);

app.post('/update', function(req, res) {
    console.log(req.body); // the posted data
});
Walter Roman
sumber
29
Untuk mem-parsing json body diperlukan untuk menambahkan baris berikutapp.use(bodyParser.json())
Camilo Silva
1
@ cml.co apakah ada alasan app.use(bodyParser.urlencoded({ extended: true })yang juga diperlukan? Saya memposting dokumen yang agak rumit sebagai JSON dalam permintaan, dan extended: falsetidak berfungsi. Hanya ketika saya mengaturnya menjadi true, permintaan diurai dengan benar.
Pengguna Web
3
Hanya sebuah catatan. Harus menggunakan app.use(bodyParser.urlencoded({ extended: true }));DAN app.use(bodyParser.json())untuk mendapatkan data json pada pengaturan server AWS Linux dengan NodeJS dan Express.
David
24
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json())

var port = 9000;

app.post('/post/data', function(req, res) {
    console.log('receiving data...');
    console.log('body is ',req.body);
    res.send(req.body);
});

// start the server
app.listen(port);
console.log('Server started! At http://localhost:' + port);

Ini akan membantu Anda. Saya menganggap Anda mengirim tubuh di json.

Gautam
sumber
Saya selalu lupa menambahkan bodyParser.json () bit x_x terima kasih!
Jonny Asmar
14

Untuk 2019, Anda tidak perlu menginstal body-parser.

Kamu bisa memakai:

var express = require('express');
var app = express();
app.use(express.json())
app.use(express.urlencoded({extended: true}))
app.listen(8888);
app.post('/update', function(req, res) {
    console.log(req.body); // the posted data
});
Shivam Gupta
sumber
8

Ini dapat dicapai tanpa body-parserketergantungan juga, mendengarkan request:datadan request:enddan mengembalikan respons pada akhir permintaan, lihat contoh kode di bawah ini. ref: https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/#request-body

var express = require('express');
var app = express.createServer(express.logger());

app.post('/', function(request, response) {

    // push the data to body
    var body = [];
    request.on('data', (chunk) => {
      body.push(chunk);
    }).on('end', () => {
      // on end of data, perform necessary action
      body = Buffer.concat(body).toString();
      response.write(request.body.user);
      response.end();
    });
});
Manivannan
sumber
3

Coba ini:

response.write(JSON.stringify(request.body));

Itu akan mengambil objek yang bodyParsertelah dibuat untuk Anda dan mengubahnya kembali menjadi string dan menulisnya ke respons. Jika Anda ingin badan permintaan yang tepat (dengan spasi yang sama, dll), Anda akan perlu datadan endpendengar melekat pada permintaan sebelumnya dan membangun potongan string dengan potongan seperti yang Anda lihat dalam kode sumber parsing json dari terhubung .

Peter Lyons
sumber
1

Apa yang Anda klaim "coba lakukan" adalah persis apa yang Anda tulis dalam kode yang berfungsi "seperti yang diharapkan" saat Anda memintanya dengan ikal.

Kesalahan yang Anda dapatkan tampaknya tidak terkait dengan salah satu kode yang Anda tunjukkan kepada kami.

Jika Anda ingin mendapatkan permintaan mentah, aktifkan penangan requestuntuk datadan endacara (dan, tentu saja, hapus semua permintaan dari express.bodyParser()). Perhatikan bahwa dataperistiwa akan terjadi dalam potongan, dan bahwa kecuali jika Anda menetapkan penyandian untuk dataperistiwa potongan tersebut akan menjadi buffer, bukan string.

ebohlman
sumber
itu adalah kesalahan salin-tempel; Maksud saya request.bodydan tidak request.body.user, dan saya memperbaikinya sekarang. By the way, var reqBody = request.body;itu dan masih benar dan ketika Anda mencobanya Anda akan mendapatkan kesalahan yang saya dapatkan. Bagaimanapun, dapatkah Anda memberi contoh tentang pengaturan handler pada request; Saya sepertinya tidak menemukannya di panduan kilat.
TheBlueSky
1

Jika Anda cukup malas untuk membaca potongan data posting. Anda bisa menempelkannya di bawah baris untuk membaca json.

Di bawah ini untuk TypeScript yang serupa dapat dilakukan untuk JS juga.

app.ts

 import bodyParser from "body-parser";
 // support application/json type post data
 this.app.use(bodyParser.json());
 // support application/x-www-form-urlencoded post data
 this.app.use(bodyParser.urlencoded({ extended: false }));

Di salah satu pengontrol Anda yang menerima penggunaan panggilan POST seperti yang ditunjukkan di bawah ini

userController.ts

 public async POSTUser(_req: Request, _res: Response) {
   try {
          const onRecord = <UserModel>_req.body;
           /* Your business logic */
           _res.status(201).send("User Created");
        }
    else{
           _res.status(500).send("Server error");
           }        
   };

_req.body harus mem-parsing Anda data json ke dalam Model TS Anda.

Shujaath Khan
sumber
1
Saya tidak yakin apakah Anda mencoba mendorong atau mengecilkan hati orang untuk menggunakan jawaban Anda dengan menyebut mereka malas :)
TheBlueSky
1

Saya benar-benar baru di JS dan ES, tetapi yang tampaknya berhasil bagi saya hanyalah ini:

JSON.stringify(req.body)

Beri tahu saya jika ada yang salah dengan itu!

balintn
sumber
persis apa yang saya butuhkan
Josef Henn
0

Instal Body Parser dengan perintah di bawah ini

$ npm install --save body-parser

Konfigurasikan Parser Tubuh

const bodyParser = require('body-parser');
app.use(bodyParser);
app.use(bodyParser.json()); //Make sure u have added this line
app.use(bodyParser.urlencoded({ extended: false }));
Arun Abimanyu
sumber
-3

Anda menggunakan kode berikut untuk mencatat data posting:

router.post("/users",function(req,res){
    res.send(JSON.stringify(req.body, null, 4));
});
Chandra Kumar
sumber
2
Jawaban yang diberikan tidak lengkap tanpa menyertakan modul body-parser.
gramcha