Express.js req.corps indéfini
J'ai ceci 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.something
dans mes routes, je reçois une erreur indiquant que 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 l'absence de app.use(express.bodyParser());
, mais comme vous pouvez le voir je l'appelle avant de les routes.
Aucune idée?
20 réponses
Vous devez vous assurer de définir toutes les configurations avant de définir les routes. 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' });
});
Dernières versions D'Express (4.x) a dissocié le middleware du cadre de base. Si vous avez besoin de body parser, vous devez l'installer séparément
npm install body-parser --save
Et puis faites ceci 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())
Non. Vous devez utiliser app.use(express.bodyParser())
avant app.use(app.router)
. En fait, app.use(app.router)
devrait être la dernière chose que vous appelez.
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 les routes
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.json());
L'en-tête Content-Type in request est très important, surtout lorsque vous postez les données de curl ou de tout autre outil.
Assurez-vous d'utiliser quelque chose comme application/x-www-form-urlencoded, application/json ou autres, cela dépend de vos données post. Laisser ce champ vide va confondre Express.
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...
// 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())
Express.bodyParser () doit être dit quel type de contenu c'est qu'il analyse. Par conséquent, vous devez vous assurer que lorsque vous exécutez une requête POST, vous incluez l'en-tête "Content-Type". Sinon, bodyParser peut ne pas savoir quoi faire avec le corps de votre requête 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 de définir ce champ d'en-tête utilisant n'importe quelle convention est appropriée.
On dirait que l'analyseur de corps n'est plus livré 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.
Cela m'est arrivé aujourd'hui. Aucune des solutions ci-dessus ne fonctionne pour moi. Mais un peu de googling m'a aidé à résoudre ce problème. Je code pour WeChat 3rd party server.
Les choses deviennent légèrement plus compliquées lorsque votre nœud.l'application js nécessite la lecture de données POST en streaming, telles qu'une demande d'un client REST. Dans ce cas, la propriété "readable" de la requête sera définie sur true et les données POST doivent être lues en morceaux afin de collecter tout le contenu.
Pour travailler, vous devez app.utilisation(app.routeur) après app.utilisation(express.bodyParser()), comme ça:
app.use(express.bodyParser())
.use(express.methodOverride())
.use(app.router);
var bodyParser = require('body-parser');
app.use(bodyParser.json());
Cela a sauvé ma journée.
Perdu beaucoup de temps:
Selon le type de contenu dans votreclient demande
le serveur devrait avoir différents, l'un des app ci-dessous.utiliser ():
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-tête ci-dessous:
Content-Type: "text/xml"
Donc, côté serveur, j'ai utilisé:
app.use(bodyParser.text({type: 'text/xml'}));
Ensuite, req.le corps a bien fonctionné.
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 docs: https://www.npmjs.com/package/body-parser#bodyparserurlencodedoptions
Vous pouvez utiliser express corps de l'analyseur.
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
Express 4, A construire-dans l'analyseur de corps. Pas besoin d'installer un analyseur de corps séparé. Donc ci-dessous fonctionnera:
export const app = express();
app.use(express.json());
Dans le cas où vous publiez un message SOAP, vous devez utiliser l'analyseur de corps brut:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.raw({ type: 'text/xml' }));
En S'appuyant sur @ kevin-xue dit, le type de contenu doit être déclaré. Dans mon cas, cela ne se produisait qu'avec IE9 car XDomainRequest ne définit pas de type de contenu , donc bodyparser et expressjs ignoraient le corps de la requête.
J'ai contourné cela en définissant explicitement le type de contenu avant de passer la requête à body parser, 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());
Crédit à @spikeyang pour la bonne réponse (fournie ci-dessous). Après avoir lu l'article suggéré joint au post, j'ai décidé de partager ma solution.
Quand utiliser?
La solution nécessitait que vous utilisiez le routeur express pour en profiter.. si: Si vous avez essayé d'utiliser la réponse acceptée sans succès, utilisez simplement copier-coller 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)
Au cas où quelqu'un rencontrerait le même problème que moi; j'utilise un préfixe d'url comme
http://example.com/api/
Qui a été configuré avec le routeur
app.use('/api', router);
Et 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 bodyparser au-dessus de app.use('/api', router);
Finale
// 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);