จะเข้าถึงเนื้อหาคำขอเมื่อ POSTing โดยใช้ Node.js และ Express ได้อย่างไร


175

ฉันมีรหัส Node.js ต่อไปนี้:

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

ตอนนี้ถ้าฉันโพสต์สิ่งที่ชอบ:

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

ฉันได้รับSomeoneตามที่คาดไว้ ตอนนี้ถ้าฉันต้องการได้รับร่างกายเต็มร้องขอ? ฉันพยายามทำresponse.write(request.body)แต่ Node.js เกิดข้อยกเว้นว่า " อาร์กิวเมนต์แรกต้องเป็นสตริงหรือบัฟเฟอร์ " จากนั้นไปที่ "infinite loop" โดยมีข้อยกเว้นที่ระบุว่า " ไม่สามารถตั้งค่าส่วนหัวได้หลังจากถูกส่ง "; นี้แม้จะยังเป็นความจริงถ้าฉันไม่แล้วเขียนvar reqBody = request.body;response.write(reqBody)

มีปัญหาอะไรที่นี่

นอกจากนี้ฉันสามารถรับคำขอแบบดิบโดยexpress.bodyParser()ไม่ใช้ได้หรือไม่


ดูเหมือนว่ามีบางอย่างด้วยresponse.write(reqBody); เมื่อฉันใช้response.send(reqBody)สิ่งที่มีการปรับการทำงาน ... และใช่ฉันใช้หลังจากresponse.end response.write
TheBlueSky

คำตอบ:


161

Express 4.0 ขึ้นไป:

$ npm install --save body-parser

จากนั้นในแอปโหนดของคุณ:

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

Express 3.0 และต่ำกว่า:

ลองผ่านสิ่งนี้ในการโทรของคุณ:

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

และทำให้แน่ใจว่าข้อมูลของคุณอยู่ในรูปแบบ JSON:

{"user":"someone"}

นอกจากนี้คุณสามารถใช้ console.dir ในรหัส node.js ของคุณเพื่อดูข้อมูลภายในวัตถุดังตัวอย่างต่อไปนี้:

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

คำถามอื่นนี้อาจช่วย: วิธีรับ JSON ในคำขอ node.js POST ด่วน

หากคุณไม่ต้องการใช้ bodyParser ลองดูคำถามอื่น ๆ นี้: https://stackoverflow.com/a/9920700/446681


ฉันลองใช้curl -d {"user":"Someone"} -H "Content-Type: application/json" --url http://localhost:5000แต่มันทำให้ฉันมีข้อผิดพลาด " โทเค็นที่ไม่คาดคิด " นั่นเป็นเหตุผลที่ฉันเปลี่ยนไปใช้การโทรที่กล่าวถึงในโพสต์ดั้งเดิมของฉัน
TheBlueSky

ฉันกำลังทำเครื่องหมายคำตอบนี้เนื่องจากลิงก์stackoverflow.com/a/9920700/446681
TheBlueSky

40
express.bodyParser()เลิกใช้ใน Express 4.x ใช้npmjs.org/package/body-parserแทน
ลัค

@TheBlueSky สาเหตุที่คุณได้รับ "Unken token u" เป็นเพราะเชลล์ใช้เครื่องหมายคำพูดคู่ของคุณ echo any"thing"สิ่งเดียวกันที่เกิดขึ้นถ้าคุณทำ ข้อมูลที่คุณกำลังโพสต์ควรอยู่ในเครื่องหมายคำพูดเพื่อป้องกันเหตุการณ์นี้
Tom Fenech

11
จาก express 4.16.0 ขึ้นไปสามารถใช้ express.json () ใน app.use () ด้วยวิธีนี้ => app.use (express.json ());
Mitro

187

เริ่มต้นจากด่วน v4.16ไม่จำเป็นต้องมีโมดูลเพิ่มเติมใด ๆ เพียงแค่ใช้มิดเดิลแวร์ JSONในตัว:

app.use(express.json())

แบบนี้:

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

หมายเหตุ - body-parserขึ้นอยู่กับสิ่งนี้ขึ้นอยู่กับการแสดง

อย่าลืมส่งส่วนหัวด้วย Content-Type: application/json


14
ขอบคุณนี่เป็นคำตอบที่ดีที่สุดสำหรับ 4.16+ ไม่มีการอ้างอิงอื่น ๆ และทำงานเหมือนมีเสน่ห์!
codepleb

1
ทางออกที่ดีที่สุด / อย่างเดียวที่ฉันสามารถหาได้โดยไม่จำเป็นต้องใช้ตัวแยกวิเคราะห์
Mote Zart

41

ในฐานะของ Express 4 รหัสต่อไปนี้ปรากฏขึ้นเพื่อทำการหลอกลวง โปรดทราบว่าคุณจะต้องติดตั้งใช้body-parsernpm

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

29
สำหรับการแยกวิเคราะห์ json เนื้อความจำเป็นต้องเพิ่มบรรทัดต่อไปนี้app.use(bodyParser.json())
Camilo Silva

1
@ cml.co มีเหตุผลใด ๆ ที่app.use(bodyParser.urlencoded({ extended: true })จะยังต้อง? ฉันกำลังโพสต์เอกสารที่ค่อนข้างซับซ้อนเป็น JSON ในคำขอและextended: falseไม่ทำงาน เมื่อฉันตั้งค่าเป็นจริงคำขอจะถูกวิเคราะห์อย่างถูกต้อง
ผู้ใช้เว็บ

3
เพียงแค่ทราบ ต้องใช้app.use(bodyParser.urlencoded({ extended: true }));AND app.use(bodyParser.json())เพื่อรับข้อมูล json ในการตั้งค่าเซิร์ฟเวอร์ AWS Linux ด้วย NodeJS และ 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);

สิ่งนี้จะช่วยคุณ ฉันถือว่าคุณกำลังส่งเนื้อหาเป็น json


ฉันลืมเพิ่ม bodyParser.json () bit x_x เสมอ!
Jonny Asmar

14

สำหรับ 2019 body-parserที่คุณไม่จำเป็นต้องติดตั้ง

คุณสามารถใช้ได้:

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

8

นี้สามารถทำได้โดยไม่ต้องbody-parserพึ่งพาเช่นกันฟังrequest:dataและrequest:endและกลับตอบสนองที่สิ้นสุดของการร้องขอให้ดูด้านล่างตัวอย่างโค้ด อ้างอิง: 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();
    });
});

3

ลองสิ่งนี้:

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

ที่จะนำวัตถุที่bodyParserสร้างขึ้นมาเพื่อคุณและเปลี่ยนกลับไปเป็นสายอักขระและเขียนลงในการตอบสนอง ถ้าคุณต้องการให้ร่างกายคำขอที่แน่นอน (ที่มีช่องว่างเดียวกัน ฯลฯ ) คุณจะต้องdataและendผู้ฟังที่แนบมากับคำขอก่อนและสร้างก้อนสตริงโดยก้อนที่คุณสามารถดูในรหัส JSON แหล่งที่มาจากการแยกการเชื่อมต่อ


1

สิ่งที่คุณอ้างว่ามี "ลองทำ" เป็นสิ่งที่คุณเขียนในรหัสที่ใช้งานได้ "ตามที่คาดไว้" เมื่อคุณเรียกใช้ด้วย curl

ข้อผิดพลาดที่คุณได้รับดูเหมือนจะไม่เกี่ยวข้องกับรหัสใด ๆ ที่คุณแสดงให้เราเห็น

หากคุณต้องการรับคำร้องขอแบบดิบให้ตั้งค่าตัวจัดการเปิดrequestสำหรับdataและendเหตุการณ์ (และแน่นอนลบการร้องขอใด ๆ ของexpress.bodyParser()) โปรดทราบว่าdataเหตุการณ์จะเกิดขึ้นในกลุ่มและยกเว้นว่าคุณได้ตั้งค่าการเข้ารหัสสำหรับdataเหตุการณ์ชิ้นนั้นจะเป็นบัฟเฟอร์ไม่ใช่สตริง


นั่นเป็นความผิดพลาดจากการคัดลอกวาง ฉันหมายถึงrequest.bodyและไม่request.body.userและฉันแก้ไขตอนนี้ โดยวิธีการที่var reqBody = request.body;ถูกและยังคงถูกต้องและเมื่อคุณลองคุณจะได้รับข้อผิดพลาดที่ฉันได้รับ อย่างไรก็ตามคุณสามารถโปรดให้ตัวอย่างเกี่ยวกับการตั้งจัดการบนrequest; ฉันดูเหมือนจะไม่พบมันในคู่มือด่วน
TheBlueSky

1

หากคุณขี้เกียจพอที่จะอ่านข้อมูลโพสต์ คุณสามารถวางบรรทัดด้านล่างเพื่ออ่าน json

ด้านล่างสำหรับ TypeScript ที่คล้ายกันสามารถทำได้สำหรับ JS เช่นกัน

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

ในตัวควบคุมใด ๆ ของคุณที่รับการเรียกใช้ POST ดังที่แสดงด้านล่าง

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 ควรแยกวิเคราะห์ข้อมูล json ของคุณใน TS Model ของคุณ


1
ฉันไม่แน่ใจว่าคุณกำลังพยายามส่งเสริมหรือกีดกันผู้คนให้ใช้คำตอบของคุณโดยการเรียกพวกเขาขี้เกียจ :)
34911

1

ฉันใหม่สำหรับ JS และ ES อย่างแน่นอน แต่สิ่งที่ฉันคิดว่าใช้ได้สำหรับฉันก็คือ:

JSON.stringify(req.body)

แจ้งให้เราทราบหากมีอะไรผิดปกติกับมัน!


สิ่งที่ฉันต้องการ
Josef Henn

0

ติดตั้ง Body Parser ตามคำสั่งด้านล่าง

$ npm install --save body-parser

กำหนดค่า Body Parser

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

-3

คุณใช้รหัสต่อไปนี้เพื่อบันทึกข้อมูลการโพสต์:

router.post("/users",function(req,res){
    res.send(JSON.stringify(req.body, null, 4));
});

2
คำตอบที่ได้รับไม่สมบูรณ์โดยไม่รวมโมดูลตัวแยกวิเคราะห์
gramcha
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.