Express.js req.body undefined

292

У меня это как конфигурация моего сервера Express

app.use(app.router); 
app.use(express.cookieParser());
app.use(express.session({ secret: "keyboard cat" }));
app.set('view engine', 'ejs');
app.set("view options", { layout: true });
//Handles post requests
app.use(express.bodyParser());
//Handles put requests
app.use(express.methodOverride());

Но все же, когда я спрашиваю req.body.somethingв своих маршрутах, я получаю ошибку, указывающую на это body is undefined. Вот пример маршрута, который использует req.body:

app.post('/admin', function(req, res){
    console.log(req.body.name);
});

Я читал, что эта проблема вызвана отсутствием, app.use(express.bodyParser());но, как вы можете видеть, я называю это перед маршрутами.

Любая подсказка?

Masiar
источник

Ответы:

296

Вы должны убедиться, что вы определяете все конфигурации ДО определения маршрутов. Если вы это сделаете, вы можете продолжать использовать express.bodyParser().

Пример таков:

var express = require('express'),
    app     = express(),
    port    = parseInt(process.env.PORT, 10) || 8080;

app.configure(function(){
  app.use(express.bodyParser());
  app.use(app.router);
});

app.listen(port);

app.post("/someRoute", function(req, res) {
  console.log(req.body);
  res.send({ status: 'SUCCESS' });
});
Марк Бонано
источник
9
Это сработало для меня. Примечание. К сожалению, в некоторых руководствах есть люди (вроде меня), которые ставят маршруты перед app.configure (). В моем случае это было в форме app.get / post и т. Д. И require (), включая их.
bendman
1
Большое спасибо, я устранял эту проблему целый день.
jfplataroti
11
Начиная с Express 4, app.use (app.router) удаляется. пожалуйста, смотрите документацию github.com/visionmedia/express/wiki/New-features-in-4.x
Джонатан Онг
15
Начиная с Express 4, промежуточные программы, такие как bodyParser, больше не связаны с Express и должны устанавливаться отдельно. Вы можете найти больше информации здесь: github.com/senchalabs/connect#middleware .
andrea.rinaldi
2
Спасибо. Этому ответу более 2 лет, и он продолжает помогать людям, попавшим в беду :)
Лоренцо Маркон,
277

Последние версии Express (4.x) отделили промежуточное программное обеспечение от базовой платформы. Если вам нужен парсер тела, вам нужно установить его отдельно

npm install body-parser --save

а затем сделайте это в своем коде

var bodyParser = require('body-parser')
var app = express()

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())
сойка
источник
2
Я недавно обновился, чтобы выразить 4.x. Первоначально, когда я пытался войти в req.body, он показывал мне неопределенное. После того, как я установил и использовал body-parser, он дает мне ожидаемые значения req.body. :)
Alok Adhao
Я нашел это полезным, пытаясь понять, почему мои POST-запросы не работают с json-сервером.
freethebees
Спас мой день, особенно часть 'app.use (bodyParser.json ())'. Спасибо брат ! : D
neaGaze
Это должен быть принятый ответ, потому что он полностью работает для Express 4! Спасибо, сэр!
Объединить
2
app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()) спас меня !!
Прамеш Баджрачарья
71

Вы должны использовать app.use(express.bodyParser())раньше app.use(app.router). На самом деле, app.use(app.router)должно быть последнее, что вы называете.

danmactough
источник
Даже перемещение app.use(app.router)по .useвызовам не решает проблему :(.
Masiar
Хорошо, после небольшого количества попыток я решил это, используя app.use(require('connect').bodyParser());вместо app.use(express.bodyParser());.
Масиар
да, ответ верен даже при использовании var router=express.Router();
Истак Ахмед
1
Небольшое дополнение, вы все равно должны вызывать промежуточное ПО для обработки ошибок после app.router
крафт
БЛАГОСЛОВЛЯЕТ ДАННЫЙ КОММЕНТАРИЙ
Ke Ke
40

Сначала убедитесь, что вы установили модуль npm с именем body-parser, вызвав:

npm install body-parser --save

Затем убедитесь, что вы включили следующие строки перед вызовом маршрутов

var express = require('express');
var bodyParser = require('body-parser');
var app = express();

app.use(bodyParser.json());
Анкит Каушик
источник
Если он использует express.json, то зачем импортировать body-parser?
Сан-Соло,
38

Express 4, имеет встроенный парсер тела. Не нужно устанавливать отдельный body-parser. Так что ниже будет работать:

export const app = express();
app.use(express.json());
TechTurtle
источник
37

Content-Type в заголовке запроса действительно важен, особенно когда вы публикуете данные из curl или любых других инструментов.

Убедитесь, что вы используете что-то вроде application / x-www-form-urlencoded, application / json или других, это зависит от ваших почтовых данных. Оставьте это поле пустым, чтобы запутать Express.

Кевин Сюэ
источник
12
+1 Это была проблема для меня. Я использовал Postman for Chrome для тестирования API-интерфейса JSON, встроенного в REST, но каждый раз получаемый Express объект был пустым. Оказывается, Почтальон по умолчанию ничего не добавляется автоматически «Content-Type: приложения / JSON» заголовка , даже если вы выбираете сырые> JSON.
Джордан
@Jordan +1 Спасибо за указание на это. На самом деле я только что проверил свои заголовки и вижу, что он по-прежнему установлен на «text / plain», хотя я выбрал «json».
инженер
Тьфу ... 7 лет спустя, и это все еще то, что
сбивает
33

Как уже написано под одним комментарием, я решил это с помощью

app.use(require('connect').bodyParser());

вместо того

app.use(express.bodyParser());

Я до сих пор не знаю, почему простое express.bodyParser()не работает ...

Masiar
источник
1
@Masiar Это не работает для меня. Я использую ExpressJS 4 и я получаю ошибку, как это. Ошибка: не удается найти модуль 'connect'
Jeyarathnem Jeyachanthuru
1
@JeyTheva - довольно старое решение, поэтому за это время все могло измениться. Я предлагаю вам попробовать установить connectмодуль через npm install connectи повторить попытку. Это единственное, о чем я могу подумать, прочитав вывод вашей ошибки.
Масиар
4
Вот последняя документация для решения этой проблемы: npmjs.com/package/body-parser Для тех, кто сталкивался с этой проблемой «post express 4», для меня работало то, что я установил Content-Typeзаголовок application/json.
Грант Игон
3
Вот последняя документация для решения этой проблемы: npmjs.com/package/body-parser После установки body-parser он все равно не работает. Что работало, так это установление Content-Typeзаголовка, application/jsonкогда я выполнял свой запрос.
Грант Игон
1
application/jsonvs text/jsonв запросе работает, как предложено @GrantEagon.
Strider
21
// Require body-parser (to receive post data from clients)

var bodyParser = require('body-parser');

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

// parse application/json

app.use(bodyParser.json())
ASHISH RANJAN
источник
20

Добавьте в свой app.js

до вызова роутера

const app = express();
app.use(express.json());
abdesselam
источник
2
ты спас мой день человек! Ключ добавить строку перед вызовом маршрутизатора
ubaldisney
Эта вещь спасла меня. Слава :)
Фаррух Файзи
12

Похоже, что парсер тела больше не поставляется с экспресс. Возможно, нам придется установить его отдельно.

var express    = require('express')
var bodyParser = require('body-parser')
var app = express()

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())

// parse application/vnd.api+json as json
app.use(bodyParser.json({ type: 'application/vnd.api+json' }))
app.use(function (req, res, next) {
console.log(req.body) // populated!

Обратитесь к странице git https://github.com/expressjs/body-parser для получения дополнительной информации и примеров.

Praneesh
источник
1
Похоже, что это новый формат Express 4.x и работал для меня. Упомянутый в других ответах express.bodyParser () не работает в 4.x.
DustinB
10

На случай, если кто-нибудь столкнется с той же проблемой, что и я; Я использую префикс URL, как

http://example.com/api/

который был настроен с маршрутизатором

app.use('/api', router); 

и тогда у меня было следующее

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

Что решило мою проблему, поместив конфигурацию bodyparser выше app.use('/api', router);

окончательный

// setup bodyparser
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));

//this is a fix for the prefix of example.com/api/ so we dont need to code the prefix in every route
    app.use('/api', router); 
Джефф Бигли
источник
9

express.bodyParser () нужно сообщить, какой тип контента он анализирует. Поэтому вам необходимо убедиться, что при выполнении запроса POST вы включаете заголовок «Content-Type». В противном случае bodyParser может не знать, что делать с телом вашего запроса POST.

Если вы используете curl для выполнения запроса POST, содержащего некоторый объект JSON в теле, это будет выглядеть примерно так:

curl -X POST -H "Content-Type: application/json" -d @your_json_file http://localhost:xxxx/someRoute

Если вы используете другой метод, просто установите это поле заголовка, используя любое соглашение.

ab107
источник
8

Используйте app.use (bodyparser.json ()); до маршрутизации. // app.use ("/ api", маршруты);

user1614168
источник
7

Вы можете попробовать добавить эту строку кода вверху (после ваших требований require):

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

Что касается причин, почему это работает, ознакомьтесь с документами: https://www.npmjs.com/package/body-parser#bodyparserurlencodedoptions

Энтони Кантелано
источник
Я имею в виду, ваш ответ правильный, но он ничем не отличается от других.
Двонстон
7

Большую часть времени req.body не определен из-за отсутствия парсера JSON

const express = require('express');
app.use(express.json());

может отсутствовать для парсера тела

const bodyParser  = require('body-parser');
app.use(bodyParser.urlencoded({extended: true}));

а иногда это не определено из-за происхождения кросса, поэтому добавьте их

const cors = require('cors');
app.use(cors())
король нео
источник
5

Это произошло со мной сегодня. Ни одно из вышеперечисленных решений не работает для меня. Но небольшое прибегание к помощи помогло мне решить эту проблему. Я пишу для wechat стороннего сервера.

Все становится немного сложнее, когда вашему приложению node.js требуется чтение потоковых данных POST, например, запрос от клиента REST. В этом случае для свойства запроса «readable» будет задано значение true, а данные POST должны читаться порциями, чтобы собрать весь контент.

http://www.primaryobjects.com/CMS/Article144

spikeyang
источник
В публикации упоминается, что отправка HTML-формы отличается от запроса клиента REST. не оба http запрос? Итак, POST - это единственный случай, который требует потоковой передачи?
j10
5

Потрачено много времени:

В зависимости от Content-Type в вашем клиентском запросе сервер должен иметь разные, один из ниже app.use ():

app.use(bodyParser.text({ type: 'text/html' }))
app.use(bodyParser.text({ type: 'text/xml' }))
app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }))
app.use(bodyParser.json({ type: 'application/*+json' }))

Источник: https://www.npmjs.com/package/body-parser#bodyparsertextoptions

Пример:

Для меня, на стороне клиента, у меня был ниже заголовок:

Content-Type: "text/xml"

Итак, на стороне сервера я использовал:

app.use(bodyParser.text({type: 'text/xml'}));

Затем требовалось, чтобы все работало нормально.

Манохар Редди Поредди
источник
5

в Express 4 это действительно просто

const app = express()
const p = process.env.PORT || 8082

app.use(express.json()) 
Херардо Баутиста
источник
4

Для работы вам нужно app.use (app.router) после app.use (express.bodyParser ()) , вот так:

app.use(express.bodyParser())
   .use(express.methodOverride())
   .use(app.router);
HenioJR
источник
1
Ваш комментарий и фрагмент кода противоречивы. Сначала вы говорите , что вы должны использовать app.useна app.routerперед тем, express.bodyParserно ваш код явно указывает на то, что это после того, как . Так что это?
Леви Робертс
1
Извини чувак. Вам нужно использовать app.router после express.bodyParser.
HenioJR
1
Спасибо @LeviRoberts
HenioJR
4
var bodyParser = require('body-parser');
app.use(bodyParser.json());

Это спасло мой день.

isdot
источник
4

Эта проблема может быть из-за того, что вы не используете body-parser ( ссылка )

var express = require('express');
var bodyParser  = require('body-parser');

var app = express();
app.use(bodyParser.json());
Arindam
источник
3

Я решил это с:

app.post('/', bodyParser.json(), (req, res) => {//we have req.body JSON
});
Кккк кккк
источник
3

Это также одна из возможностей : Убедитесь, что вы должны написать этот код перед маршрутом в файле app.js (или index.js).

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
Инамур Рахман
источник
2

Вы можете использовать экспресс парсер тела.

var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
Кулдип Мишра
источник
2

Последняя версия Express уже имеет встроенный body-parser. Таким образом, вы можете использовать:

const express = require('express);
... 
app.use(express.urlencoded({ extended: false }))
.use(express.json());
LEMUEL ADANE
источник
1

В случае, если вы публикуете SOAP-сообщение, вам нужно использовать raw body parser:

var express = require('express');
var app = express();
var bodyParser = require('body-parser');

app.use(bodyParser.raw({ type: 'text/xml' }));
opewix
источник
1

Опираясь на @ kevin-xue, тип контента должен быть объявлен. В моем случае это происходило только с IE9, потому что XDomainRequest не устанавливает тип контента , поэтому bodyparser и expressjs игнорировали тело запроса.

Я справился с этим, установив явно тип содержимого перед передачей запроса в анализатор тела, например так:

app.use(function(req, res, next) {
    // IE9 doesn't set headers for cross-domain ajax requests
    if(typeof(req.headers['content-type']) === 'undefined'){
        req.headers['content-type'] = "application/json; charset=UTF-8";
    }
    next();
})
.use(bodyParser.json());
purpletonic
источник
1

Кредит @spikeyang за большой ответ (приводится ниже). Прочитав предложенную статью, приложенную к сообщению, я решил поделиться своим решением.

Когда использовать?

Решение потребовало, чтобы вы использовали экспресс-маршрутизатор, чтобы насладиться им. Итак: Если вы пытались использовать принятый ответ безуспешно, просто используйте функцию копирования и вставки:

function bodyParse(req, ready, fail) 
{
    var length = req.header('Content-Length');

    if (!req.readable) return fail('failed to read request');

    if (!length) return fail('request must include a valid `Content-Length` header');

    if (length > 1000) return fail('this request is too big'); // you can replace 1000 with any other value as desired

    var body = ''; // for large payloads - please use an array buffer (see note below)

    req.on('data', function (data) 
    {
        body += data; 
    });

    req.on('end', function () 
    {
        ready(body);
    });
}

и назовите это как:

bodyParse(req, function success(body)
{

}, function error(message)
{

});

ПРИМЕЧАНИЕ: для больших полезных нагрузок - используйте буфер массива ( больше @ MDN )

ЯМЗ
источник
Пакет bodyParser обычно используется и переводит полезную нагрузку в объект body. как предусмотрено в других ответах
Schuere
1

Если вы используете какой-либо внешний инструмент для выполнения запроса, обязательно добавьте заголовок:

Content-Type: application/json

работе 33
источник
Этот помог мне, я работал с Почтальоном, спасибо, приятель.
Р. Гурунг
1

Для тех, у кого не работает ни один из приведенных выше ответов, я должен был включить cors между своим клиентом и экспрессом.

Вы можете сделать это либо:

  1. Загрузка и включение расширения CORS для вашего браузера, например:

    https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en

    для Chrome,

или

  1. Добавление строк

    var cors=require('cors');
    
    app.use(cors());

на вашу экспресс- app.jsстраницу. (После npm install cors)

LMB
источник