Як отримати доступ до тіла запиту при 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 кидає виняток, кажучи, що " перший аргумент повинен бути рядком або буфером ", а потім переходить до "нескінченного циклу" за винятком, який говорить " Неможливо встановити заголовки після їх надсилання. "; це також справедливо, навіть якщо я це робив, var reqBody = request.body;а потім писав response.write(reqBody).

У чому тут питання?

Також я можу просто отримати необроблений запит без використання express.bodyParser()?


Здається, є щось із response.write(reqBody); коли я використовую response.send(reqBody)речі, добре працюють ... і так, я використовую response.endпісля response.write.
TheBlueSky

Відповіді:


161

Експрес 4.0 і вище:

$ npm install --save body-parser

А потім у вашому додатку для вузла:

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

Експрес 3.0 і нижче:

Спробуйте передати це у своєму дзвінку CURL:

--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 у експресному запиті POST на node.js?

Якщо ви не хочете використовувати bodyParser, перегляньте це інше питання: https://stackoverflow.com/a/9920700/446681


Я спробував використовувати, curl -d {"user":"Someone"} -H "Content-Type: application/json" --url http://localhost:5000але це дало мені помилку " Несподіваний маркер u ", тому я перейшов на згаданий дзвінок у своєму початковому дописі.
TheBlueSky

Я маркування це як відповідь через посилання stackoverflow.com/a/9920700/446681
TheBlueSky

40
express.bodyParser()застаріла в Express 4.x. Використовуйте замість npmjs.org/package/body-parser .
Люк

@TheBlueSky причиною, чому ви отримали "Несподіваний маркер u", було те, що оболонка споживала ваші подвійні лапки. Те саме відбувається, якщо ви робите echo any"thing". Дані, які ви публікуєте, повинні бути в межах цитат, щоб не допустити цього.
Том Фенех

11
З Express 4.16.0 або вище можливо таким чином використовувати express.json () в app.use () => app.use (express.json ());
Мітро

187

Починаючи з express 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-parserкористування 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
});

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.
Девід

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 () x_x дякую!
Джоні Асмар

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

Те, що ви стверджуєте, що "намагався робити", - це саме те, що ви написали в коді, який працює "як очікувалося", коли ви викликаєте його з завитком.

Отримана помилка, схоже, не пов’язана з будь-яким кодом, який ви нам показали.

Якщо ви хочете отримати необроблений запит, увімкніть обробники 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-моделі.


1
Я не впевнений, чи намагаєтесь ви заохотити чи відмовити людей використовувати свою відповідь, називаючи їх ледачими :)
TheBlueSky

1

Я абсолютно новачок у JS та ES, але те, що, здається, працює для мене, це саме це:

JSON.stringify(req.body)

Дайте мені знати, якщо в цьому щось не так!


саме те, що мені було потрібно
Йозеф Генн

0

Встановіть Body Parser за допомогою команди нижче

$ npm install --save 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
Дана відповідь є неповною, не включаючи модуль аналізатора тіла.
грамча
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.