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?

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

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

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.


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

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

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.


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


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

20

Ajoutez votre app.js

avant l'appel du routeur

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

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.


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

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.


8

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



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

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


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


5

dans Express 4, c'est vraiment simple

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

app.use(express.json()) 

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

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.


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

3

Je l'ai résolu avec:

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

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

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

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

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

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

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 )


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


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)

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.