req.body пусті на дописи


255

Раптом це сталося з усіма моїми проектами.

Щоразу, коли я створю повідомлення в nodejs, використовуючи експрес та тест-парсер req.body, це порожній об'єкт.

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

Через ajax та листоноші він завжди порожній.

Однак за допомогою завивки

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

він працює за призначенням.

Я намагався налаштувати вручну Content-type : application/jsonв колишньому, але потім завжди отримую400 bad request

Це зводило мене з розуму.

Я подумав, що щось було оновлено в аналізаторі тіла, але я погіршив процес, і це не допомогло.

Будь-яка допомога вдячна, дякую.


16
Отже, ви намагалися явно встановити Content-Typeв листоноші? Якщо ні, то ви можете спробувати це, оскільки у мене були проблеми з тим, що листонош не надсилав Content-Type.
— mscdex

так. саме тоді я отримав 400: недійсний json
— Джозеф Дейлі

@mscdex - дякую, що я не встановив контент-туп у листоноші і
— зліз з

Для тих людей, які приїжджають сюди, тому що хочуть надсилати / завантажувати файли зі своїх API, і тому вони повинні використовувати форми-дані. Вам потрібно щось для обробки даних форми: npmjs.com/package/multer - досить популярний пакет.
— бхаскар

Незважаючи ні на що, листоноша не дуже добре поводиться з цілими числами та знаками "плаваюча" Якщо у вас є цілі чи плаваючі значення, переконайтесь, що подвійно цитувати все, і ключі, і значення
— anabeto93

Відповіді:


272

У Postman з 3 варіантів, доступних для типу вмісту, виберіть "X-www-form-urlencoded", і він повинен працювати.

Також щоб позбутися заміни повідомлення про помилку:

app.use(bodyParser.urlencoded())

З:

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

Дивіться https://github.com/expressjs/body-parser

Проміжне програмне забезпечення "тіло-аналізатор" обробляє лише JSON та дані, кодовані урленом, а не багаточастинні


Це працювало для листоноші, я не впевнений, чому це працює з ajax, оскільки я нічого не змінив.
— Джозеф Дейлі

Чомусь повідомлення в http через Angular не потрібно було кодувати URL-адресами, але дзвінки Ajax робили. Хтось знає, чому?
— youngrrrr

Це працювало для мене, чому ж не було роботи з сировинним кодуванням?
— Даніель Кобе

9
тепер body-parser вбудований у express.js просто використовуйтеapp.use(express.json());
— Sujeet Agrahari

Дуже дякую! Незважаючи на довгий час відповіді на це, він все ще актуальний.
— Spray'n'Pray

217

З Postman, щоб перевірити дії HTTP-публікації з необробленою навантаженням даних JSON, виберіть rawпараметр і встановіть такі параметри заголовка:

Content-Type: application/json

Також обов'язково загортайте будь-які рядки, які використовуються як ключі / значення у вашому навантаженні JSON, подвійними лапками.

У body-parserпакеті буде проаналізовано багаторядкові сирі навантаження JSON.

{
    "foo": "bar"
}

Тестовано в Chrome v37 та v41 з розширенням Postman v0.8.4.13 ( body-parserv1.12.2 та expressv4.12.3) із налаштуваннями нижче:

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

Коричне навантаження пошти json


О людино, як я пропустив, що я вставив об'єкт JS буквально, а не правильно відформатований об'єкт JSON ...: -S ... дякую друже!
— Уес Джонсон

Встановлення будь-яких рядків, що використовуються як ключ / значення, у подвійних лапках ... Легко пропустити, але інакше загальний вимикач угод! Дякую.
— loxyboi

Гарне використання скріншотів.
— Ксан-Кун Кларк-Девіс

Коли я використовую form-dataу Postman для розміщення даних, я завжди отримую {}теки у req.body. Чи варто встановити Content-Typeваріант?
— мінчау

56

Я зробив дійсно тупу помилку і забув визначити nameатрибути для входів у своєму HTML-файлі.

Тож замість

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

У мене це є.

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

Зараз request.bodyзаселено так:{ password: 'hhiiii' }


1
Бам. У цьому і була проблема. Дякую!
— Метт Вест

Це була саме моя проблема: введення форми без значень імен витрачало години, намагаючись розібратися в цьому. Дякую.
— karensantana

37

Я виявив, що він працює при надсиланні з типом вмісту

"додаток / json"

у поєднанні з сервером

app.use(bodyParser.json());

Тепер я можу відправити через

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

і результат доступний request.body.nameна сервері.


Дякуємо за підсумки. Я дійсно вважаю, що це найчистіше, хоча і не найпростіше рішення, оскільки ви все одно повинні надсилати правильний тип вмісту. Я думаю.
— Ксан-Кун Кларк-Девіс

це відповідь!
— Гель

У моєму випадку мені довелося змінити це наxmlHttp.send(JSON.stringify(data));
— endo64

18

Я зіткнувся з цією проблемою сьогодні, і що вирішило, це було видалити заголовок типу вмісту у Postman! Дуже дивно. Додайте його сюди, якщо це комусь допоможе.

Я дотримувався підручника BeerLocker тут: http://scottksmith.com/blog/2014/05/29/beer-locker-building-a-restful-api-with-node-passport/


2
у мене було те саме питання. маючи заголовок "не відмічено" (і пропав сірим кольором) було недостатньо, мені довелося повністю його видалити. незважаючи на те, що кнопка джерела "</>" показує, що я не надсилав цей заголовок, коли тип вмісту перебуває в неперевіреному стані, його все одно потрібно було повністю видалити.
— theRemix

Я не можу зрозуміти, як видалити заголовки за замовчуванням у розширенні хроністи листоноші ... Ви, можливо, використовуєте додаток?
— WestleyArgentum

О, я встановив додаток, і він працює набагато краще, ніж розширення. Вибачте за шум.
— WestleyArgentum

12

Ви повинні перевірити, чи встановлено проміжне програмне забезпечення для аналізатора тіл відповідно до типу запиту (json, urlencoded).

Якщо ви встановили,

app.use(bodyParser.json());

то в листоноші вам доведеться надсилати дані як необроблені.

https://i.stack.imgur.com/k9IdQ.png скріншот листоноші

Якщо ви встановили,

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

тоді слід вибрати опцію 'x-www-form-urlencoded'.


а як мати їх обох? (bodyParser.urlencoded та bodyParser.json ()) ... який я можу використовувати у листоноші?
— TommyLeong

9

Моя проблема полягала в тому, що я створив маршрут спочатку

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

та реєстрація проміжного програмного забезпечення після маршруту

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

завдяки структурі додатків та копіюванню та склеюванню проекту разом із прикладів.

Після того, як я зафіксував замовлення на реєстрацію проміжного програмного забезпечення перед маршрутом, все працювало.


спасибі фіат, з правильним замовленням та використанням сирого вкладки він працював нарешті для мене
— Олексій

4

Навіть коли я вперше вчився node.js, коли я почав його вивчати через веб-додаток, я все це робив добре в моїй формі, я все ще не міг отримувати значення в запиті після публікації. Після тривалої налагодження я дізнався, що в тому вигляді, який я надав, enctype="multipart/form-data"завдяки якому я не зміг отримати значення. Я просто її зняв, і це працювало на мене.


так, це також працювало, щоб отримати тіло форми, але потім спричинило ще одну проблему з моєю формою - в основному файл не вдалося завантажити, як цього потрібноenctype="multipart/form-data"
— tsando,

btw, лише щоб додати до мого вище коментаря, мені вдалося налагодити цю роботу multer- дивіться документацію на npmjs.com/package/multer
— tsando

3

Здається, якщо ви не використовуєте жоден encType (типовим є application/x-www-form-urlencoded), ви отримуєте поля для введення тексту, але ви не отримаєте файл.

Якщо у вас є форма, де ви хочете розмістити текст і файл, тоді використовуйте multipart/form-dataтип кодування, а на додаток до цього використовуйте multerпроміжне програмне забезпечення. Multer проаналізує об’єкт запиту та підготує req.fileдля вас, і всі інші вхідні поля будуть доступні через req.body.


1
дякую - multerсправді було вирішенням моєї проблеми. Було б добре, якщо ви можете додати приклад того, як це використовувати як частину вашої відповіді
— tsando,

2

Подібна проблема трапилася і зі мною, я просто змішав порядок парами зворотного виклику. Переконайтесь, що ви налаштовуєте функції зворотного дзвінка у правильному порядку. Принаймні для тих, хто має таку ж проблему.

router.post('/', function(req, res){});

2

Переконайтесь, що ["key": "type", "value": "json"] & ["key": "Content-Type", "value": "application / x-www-form-urlencoded"] є у вашому заголовки запиту листоноші


2

Я вирішив це, multerяк було запропоновано вище, але вони пропустили повний робочий приклад, як це зробити. В основному це може статися, коли у вас є група форм enctype="multipart/form-data". Ось HTML для форми, яку я мав:

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

Ось як можна multerотримати значення та назви цієї форми за допомогою Express.jsта 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)
});

1

У мене була така ж проблема кілька хвилин тому, я спробував усе можливе у вищезазначених відповідях, але будь-яка з них спрацювала.

Єдине, що я зробив - це оновлення версії Node JS, я не знав, що оновлення може чимось вплинути, але це зробило.

Я встановив версію Node JS 10.15.0(остання версія), я повернувся до 8.11.3і все зараз працює. Можливо, body-parserмодуль повинен виправити це.


1

У мене не було імені в моєму введенні ... мій запит був порожнім ... рада, що закінчено, і я можу продовжувати кодування. Дякую всім!

Відповідь, яку я використав Джейсон Кім:

Тож замість

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

У мене це є

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

1

вам не слід робити це JSON.stringify(data)під час надсилання через AJAX, як показано нижче.

Це НЕ правильний код:

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

Правильний код:

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

Ключова річ, яку тут слід зазначити, - це те, що типово переконайтесь, що ви використовуєте великі літери "POST". Я бачив випадки, коли саме використання "поста" призвело до порожнього req.body.
— Метт К.

1

Якщо ви працюєте з листоношею, підтвердьте ці матеріали, коли ви запитуєте API

введіть тут опис зображення


0

Я використовував restify замість express і зіткнувся з тією ж проблемою. Рішення було зробити:

server.use(restify.bodyParser());


0

Змініть app.use(bodyParser.urlencoded());свій код на

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

і в листоноші, у Content-Typeзначенні зміни заголовка з application/x-www-form-urlencodedнаapplication/json

Та :-)


0

Дякую всім за чудові відповіді! Довгий час я шукав рішення, і на моєму боці я робив елементарну помилку: мені дзвонив bodyParser.json()зсередини функції:

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

Мені просто потрібно було це зробити, app.use(['/password'], bodyParser.json())і це спрацювало ...


0

У листоноші, навіть слідуючи за прийнятою відповіддю, я отримував порожнє тіло запиту. Виявилося, що це не проходить заголовок, названий

Content-Length : <calculated when request is sent>

Цей заголовок був за замовчуванням (разом із 5 іншими), який я відключив. Увімкніть це, і ви отримаєте орган запиту.


0

Моя проблема полягала в створенні маршруту спочатку, require("./routes/routes")(app); я перемістив його до кінця коду раніше, app.listen і він працював!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.