Express.js req.body undefined

291

Je l'ai comme configuration de mon serveur 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());

Mais quand je demande req.body.somethingdans mes itinéraires, je reçois une erreur en le signalant body is undefined. Voici un exemple de route qui utilise req.body:

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

J'ai lu que ce problème est causé par le manque de app.use(express.bodyParser());mais comme vous pouvez le voir je l'appelle avant les itinéraires.

Un indice?

Masiar
la source

Réponses:

296

Vous devez vous assurer que vous définissez toutes les configurations AVANT de définir des itinéraires. Si vous le faites, vous pouvez continuer à utiliser express.bodyParser().

Un exemple est le suivant:

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' });
});
Mark Bonano
la source
9
Cela a fonctionné pour moi. Remarque: Malheureusement, certains tutoriels proposent à des gens (comme moi) de mettre des itinéraires avant app.configure (). Dans mon cas, c'était sous la forme app.get / post etc, et un require () les incluant.
bendman
1
Merci beaucoup, j'ai résolu ce problème toute la journée.
jfplataroti
11
à partir d'Express 4, app.use (app.router) est supprimé. veuillez consulter les documents github.com/visionmedia/express/wiki/New-features-in-4.x
Jonathan Ong
15
à partir d'Express 4, les middlewares comme bodyParser ne sont plus fournis avec Express et doivent être installés séparément. Vous pouvez trouver plus d'informations ici: github.com/senchalabs/connect#middleware .
andrea.rinaldi
2
Merci. Cette réponse a plus de 2 ans et continue d'aider les personnes en difficulté :)
Lorenzo Marcon
275

Les dernières versions d'Express (4.x) ont dégroupé le middleware du framework principal. Si vous avez besoin d'un analyseur de corps, vous devez l'installer séparément

npm install body-parser --save

puis faites-le dans votre code

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())
Geai
la source
2
J'ai récemment mis à jour pour exprimer 4.x. Au début, lorsque j'essayais de me connecter à req.body, cela me montrait undefined. Une fois que j'ai installé et utilisé l'analyseur de corps, il me donne les valeurs de corps requises. :)
Alok Adhao
J'ai trouvé cela utile lorsque j'essayais de comprendre pourquoi mes demandes POST ne fonctionnaient pas avec json-server.
freethebees
J'ai sauvé ma journée, en particulier la partie «app.use (bodyParser.json ())». Merci mec ! : D
neaGaze
Cela devrait être la réponse acceptée car cela fonctionne totalement pour Express 4! Merci Monsieur!
Combinez
2
app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()) m'a sauvé !!
Pramesh Bajracharya
71

Non, vous devez utiliser app.use(express.bodyParser())avant app.use(app.router). En fait, ce app.use(app.router)devrait être la dernière chose que vous appelez.

danmactough
la source
Même se déplacer app.use(app.router)sous les .useappels ne résout pas le problème :(.
Masiar
Ok après un peu de mal, je l'ai résolu en utilisant app.use(require('connect').bodyParser());au lieu de app.use(express.bodyParser());.
Masiar
oui, la réponse est vraie même lors de l'utilisation var router=express.Router();
Istiaque Ahmed
1
Léger addendum, vous devez toujours appeler le middleware de gestion des erreurs après le routeur app.router
craft
BÉNISSEZ CE COMMENTAIRE
Ke Ke
40

Assurez-vous d'abord que vous avez installé le module npm nommé 'body-parser' en appelant:

npm install body-parser --save

Assurez-vous ensuite d'avoir inclus les lignes suivantes avant d'appeler des itinéraires

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

app.use(bodyParser.json());
Ankit kaushik
la source
S'il utilise express.json, alors pourquoi importer l'analyseur de corps?
SanSolo
38

Express 4, possède un analyseur de corps intégré. Pas besoin d'installer un analyseur de corps séparé. Donc ci-dessous fonctionnera:

export const app = express();
app.use(express.json());
TechTurtle
la source
37

Le type de contenu dans l'en-tête de demande est vraiment important, surtout lorsque vous publiez les données de curl ou de tout autre outil.

Assurez-vous que vous utilisez quelque chose comme application / x-www-form-urlencoded, application / json ou autres, cela dépend de vos données de publication. Laisser ce champ vide confondra Express.

Kevin Xue
la source
12
+1 C'était le problème pour moi. J'utilisais Postman pour Chrome pour tester une API JSON intégrée à REST, mais l'objet reçu par Express était vide à chaque fois. Il s'avère que Postman par défaut n'ajoute pas automatiquement l'en-tête «Content-Type: application / json» même si vous sélectionnez raw> json.
Jordan
@Jordan +1 Merci de l'avoir signalé. En effet, je viens de vérifier mes en-têtes et je vois qu'il est toujours réglé sur 'text / plain' même si j'ai sélectionné 'json'.
Ingénieur
Ugh ... 7 ans plus tard et c'est toujours ce qui me fait trébucher ...
Shaun314
33

Comme déjà posté sous un commentaire, je l'ai résolu en utilisant

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

au lieu de

app.use(express.bodyParser());

Je ne sais toujours pas pourquoi le simple express.bodyParser()ne fonctionne pas ...

Masiar
la source
1
@Masiar Cela ne fonctionne pas pour moi. j'utilise expressjs 4 et j'obtiens une erreur comme celle-ci. Erreur: impossible de trouver le module «connexion»
Jeyarathnem Jeyachanthuru
1
La mine @JeyTheva est une solution assez ancienne, donc les choses ont peut-être changé entre-temps. Je vous suggère d'essayer d'installer le connectmodule via npm install connectet de réessayer. C'est la seule chose à laquelle je peux penser en lisant la sortie de votre erreur.
Masiar
4
Voici la documentation la plus récente pour résoudre ce problème: npmjs.com/package/body-parser Pour ceux qui rencontrent ce problème "post express 4", ce qui a fonctionné pour moi a été de définir l'en- Content-Typetête application/json.
Grant Eagon
3
Voici la dernière documentation pour résoudre ce problème: npmjs.com/package/body-parser Après avoir installé body-parser, cela n'a toujours pas fonctionné. Ce qui a fonctionné, c'était de définir l'en- Content-Typetête application/jsonlorsque je faisais ma demande.
Grant Eagon
1
application/jsonvs text/jsondans les travaux de demande, comme suggéré par @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
la source
20

Ajoutez votre app.js

avant l'appel du routeur

const app = express();
app.use(express.json());
abdesselam
la source
2
tu as sauvé mon homme du jour! La clé est d'ajouter la ligne avant le routeur d'appel
ubaldisney
Cette chose m'a sauvé. Merci :)
Farrukh Faizy
12

Il semble que l'analyseur de corps ne soit plus expédié avec express. Nous devrons peut-être l'installer séparément.

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!

Reportez-vous à la page git https://github.com/expressjs/body-parser pour plus d'informations et d'exemples.

Praneesh
la source
1
Cela semble être le nouveau format Express 4.x et a fonctionné pour moi. Le express.bodyParser () mentionné dans d'autres réponses ne fonctionne pas dans 4.x.
DustinB
10

Au cas où quelqu'un rencontrerait le même problème que je rencontrais; J'utilise un préfixe d'URL comme

http://example.com/api/

qui a été configuré avec un routeur

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

puis j'ai eu ce qui suit

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

Ce qui a résolu mon problème était de placer la configuration du bodyparser au-dessus app.use('/api', router);

Final

// 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); 
Jeff Beagley
la source
9

express.bodyParser () doit être informé du type de contenu qu'il s'agit d'analyser. Par conséquent, vous devez vous assurer que lorsque vous exécutez une demande POST, vous incluez l'en-tête "Content-Type". Sinon, bodyParser peut ne pas savoir quoi faire avec le corps de votre demande POST.

Si vous utilisez curl pour exécuter une requête POST contenant un objet JSON dans le corps, cela ressemblerait à ceci:

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

Si vous utilisez une autre méthode, assurez-vous simplement de définir ce champ d'en-tête en utilisant la convention appropriée.

ab107
la source
8

Utilisez app.use (bodyparser.json ()); avant le routage. //. app.use ("/ api", routes);

user1614168
la source
7

Vous pouvez essayer d'ajouter cette ligne de code en haut, (après vos instructions require):

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

Quant aux raisons pour lesquelles cela fonctionne, consultez les documents: https://www.npmjs.com/package/body-parser#bodyparserurlencodedoptions

Anthony Cantellano
la source
Je veux dire, votre réponse est correcte, mais elle n'est pas différente des autres.
dwjohnston
7

La plupart du temps, req.body n'est pas défini en raison de l'analyseur JSON manquant

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

pourrait être manquant pour l'analyseur corporel

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

et parfois, il n'est pas défini en raison de l'origine des cros, alors ajoutez-les

const cors = require('cors');
app.use(cors())
roi néo
la source
5

Cela m'est arrivé aujourd'hui. Aucune des solutions ci-dessus ne fonctionne pour moi. Mais un peu de recherche sur Google m'a aidé à résoudre ce problème. Je code pour un serveur tiers wechat.

Les choses deviennent un peu plus compliquées lorsque votre application node.js nécessite la lecture de données POST en streaming, comme une demande d'un client REST. Dans ce cas, la propriété de la requête "lisible" sera définie sur true et les données POST doivent être lues par blocs afin de collecter tout le contenu.

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

spikeyang
la source
la publication mentionne la soumission du formulaire HTML comme différente de la demande du client REST. ne sont pas les deux demande http? donc, POST est le seul cas qui nécessite un streaming?
j10
5

Perdu beaucoup de temps:

Selon le type de contenu dans votre demande client,
le serveur doit avoir un autre, l'un des app.use () ci-dessous:

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

Source: https://www.npmjs.com/package/body-parser#bodyparsertextoptions

Exemple:

Pour moi, côté client, j'avais en-dessous:

Content-Type: "text/xml"

Donc, côté serveur, j'ai utilisé:

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

Ensuite, tout le monde a bien fonctionné.

Manohar Reddy Poreddy
la source
5

dans Express 4, c'est vraiment simple

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

app.use(express.json()) 
Gerardo Bautista
la source
4

Pour travailler, vous devez app.use (app.router) après app.use (express.bodyParser ()) , comme ceci:

app.use(express.bodyParser())
   .use(express.methodOverride())
   .use(app.router);
HenioJR
la source
1
Votre commentaire et votre extrait de code sont contradictoires. D' abord , vous dites que vous devez utiliser app.usesur app.routeravant , express.bodyParsermais votre code indique clairement son APRÈS. Alors c'est quoi?
Levi Roberts
1
Désolé mec. Vous devez utiliser app.router après express.bodyParser.
HenioJR
1
Merci @LeviRoberts
HenioJR
4
var bodyParser = require('body-parser');
app.use(bodyParser.json());

Cela m'a sauvé la journée.

isdot
la source
4

Ce problème peut être dû au fait que vous n'avez pas utilisé l'analyseur de corps ( lien )

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

var app = express();
app.use(bodyParser.json());
Arindam
la source
3

Je l'ai résolu avec:

app.post('/', bodyParser.json(), (req, res) => {//we have req.body JSON
});
Kkkk Kkkk
la source
3

C'est également une possibilité : assurez-vous que vous devez écrire ce code avant l'itinéraire dans votre fichier app.js (ou index.js).

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
Inamur Rahman
la source
2

Vous pouvez utiliser l'analyseur corporel express.

var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
Kuldeep Mishra
la source
2

La dernière version d'Express a déjà intégré l'analyseur de corps. Vous pouvez donc utiliser:

const express = require('express);
... 
app.use(express.urlencoded({ extended: false }))
.use(express.json());
LEMUEL ADANE
la source
1

Si vous postez un message SOAP, vous devez utiliser un analyseur de corps brut:

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

app.use(bodyParser.raw({ type: 'text/xml' }));
opewix
la source
1

En s'appuyant sur @ kevin-xue, le type de contenu doit être déclaré. Dans mon cas, cela ne se produisait qu'avec IE9 parce que XDomainRequest ne définit pas de type de contenu , donc bodyparser et expressjs ignoraient le corps de la demande.

J'ai contourné cela en définissant explicitement le type de contenu avant de passer la demande à l'analyseur de corps, comme ceci:

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());
purplétonique
la source
1

Crédit à @spikeyang pour la grande réponse (ci - dessous). Après avoir lu l'article suggéré en pièce jointe, j'ai décidé de partager ma solution.

Quand utiliser?

La solution vous obligeait à utiliser le routeur express pour en profiter .. donc: Si vous avez essayé d'utiliser la réponse acceptée sans succès, utilisez simplement le copier-coller de cette fonction:

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

et appelez-le comme:

bodyParse(req, function success(body)
{

}, function error(message)
{

});

REMARQUE: pour les grandes charges utiles - veuillez utiliser un tampon de tableau ( plus @ MDN )

ymz
la source
le package bodyParser est couramment utilisé et traduit la charge utile en un objet corps. comme prévu dans d'autres réponses
Schuere
1

Si vous utilisez un outil externe pour effectuer la demande, assurez-vous d'ajouter l'en-tête:

Content-Type: application/json

Inc33
la source
Celui-ci m'a aidé, je travaillais avec Postman, merci mon pote.
R. Gurung
1

Pour toute personne pour laquelle aucune des réponses ci-dessus n'a fonctionné, j'ai dû activer les cors entre mon front-end et express.

Vous pouvez le faire soit par:

  1. Téléchargement et activation d'une extension CORS pour votre navigateur, telle que:

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

    pour Chrome,

ou par

  1. Ajout des lignes

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

à votre app.jspage express . (Après npm install cors)

lmb
la source