Comment accéder au corps de la requête lors du POST en utilisant Node.js et Express?

175

J'ai le code Node.js suivant:

var express = require('express');
var app = express.createServer(express.logger());
app.use(express.bodyParser());

app.post('/', function(request, response) {
    response.write(request.body.user);
    response.end();
});

Maintenant, si je POST quelque chose comme:

curl -d user=Someone -H Accept:application/json --url http://localhost:5000

Je reçois Someonecomme prévu. Maintenant, que faire si je veux obtenir le corps de la requête complet? J'ai essayé de faire response.write(request.body)mais Node.js lève une exception disant "le premier argument doit être une chaîne ou un tampon " puis passe à une "boucle infinie" avec une exception qui dit " Impossible de définir les en-têtes après leur envoi. "; cela est également vrai même si je l'ai fait var reqBody = request.body;et ensuite écrit response.write(reqBody).

Quel est le problème ici?

En outre, puis-je simplement obtenir la demande brute sans utiliser express.bodyParser()?

Le ciel bleu
la source
Il semble qu'il y ait quelque chose avec response.write(reqBody); quand j'utilise les response.send(reqBody)choses fonctionnent bien ... et oui, je l'utilise response.endaprès response.write.
TheBlueSky

Réponses:

161

Express 4.0 et supérieur:

$ npm install --save body-parser

Et puis dans votre application de nœud:

const bodyParser = require('body-parser');
app.use(bodyParser);

Express 3.0 et inférieur:

Essayez de transmettre ceci dans votre appel cURL:

--header "Content-Type: application/json"

et assurez-vous que vos données sont au format JSON:

{"user":"someone"}

En outre, vous pouvez utiliser console.dir dans votre code node.js pour voir les données à l'intérieur de l'objet comme dans l'exemple suivant:

var express = require('express');
var app = express.createServer();

app.use(express.bodyParser());

app.post('/', function(req, res){
    console.dir(req.body);
    res.send("test");
}); 

app.listen(3000);

Cette autre question pourrait également aider: Comment recevoir JSON dans la demande POST express node.js?

Si vous ne souhaitez pas utiliser le bodyParser, consultez cette autre question: https://stackoverflow.com/a/9920700/446681

Hector Correa
la source
J'ai essayé d'utiliser curl -d {"user":"Someone"} -H "Content-Type: application/json" --url http://localhost:5000mais cela me donnait l'erreur " U jeton inattendu ", c'est pourquoi je suis passé à l'appel mentionné dans mon message d'origine.
TheBlueSky
Je marque cela comme réponse à cause du lien stackoverflow.com/a/9920700/446681
TheBlueSky
40
express.bodyParser()est obsolète dans Express 4.x. Utilisez plutôt npmjs.org/package/body-parser .
Luc
@TheBlueSky la raison pour laquelle vous avez obtenu le "jeton inattendu u" était que le shell consommait vos guillemets. La même chose se produit si vous le faites echo any"thing". Les données que vous publiez doivent être entre guillemets pour éviter que cela ne se produise.
Tom Fenech
11
Depuis express 4.16.0 ou supérieur, il est possible d'utiliser express.json () dans app.use () de cette manière => app.use (express.json ());
Mitro
187

À partir d' express v4.16, il n'est pas nécessaire de nécessiter de modules supplémentaires, utilisez simplement le middleware JSON intégré :

app.use(express.json())

Comme ça:

const express = require('express')

app.use(express.json())    // <==== parse request body as JSON

app.listen(8080)

app.post('/test', (req, res) => {
  res.json({requestBody: req.body})  // <==== req.body will be a parsed JSON object
})

Remarque - body-parser, dont cela dépend, est déjà inclus avec express.

N'oubliez pas non plus d'envoyer l'en-tête Content-Type: application/json

rustyx
la source
14
Merci, c'est la meilleure réponse pour 4.16+ alors. Aucune autre dépendance et fonctionne comme un charme!
codepleb
1
La meilleure / seule solution que j'ai pu trouver qui n'a pas besoin de l'analyseur corporel
Mote Zart
41

À partir d'Express 4, le code suivant semble faire l'affaire. Notez que vous devrez installer en body-parserutilisant npm.

var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({ extended: false }));


app.listen(8888);

app.post('/update', function(req, res) {
    console.log(req.body); // the posted data
});
Walter Roman
la source
29
Pour analyser les corps json, il est nécessaire d'ajouter la ligne suivanteapp.use(bodyParser.json())
Camilo Silva
1
@ cml.co y a-t-il une raison app.use(bodyParser.urlencoded({ extended: true })est-elle également requise? Je poste un document assez complexe au format JSON dans la demande et je extended: falsen'ai pas fonctionné. Ce n'est que lorsque je le mets à true que la demande est correctement analysée.
Utilisateur Web
3
Juste une note. J'ai dû utiliser app.use(bodyParser.urlencoded({ extended: true }));AND app.use(bodyParser.json())pour obtenir des données json sur une configuration de serveur AWS Linux avec NodeJS et Express.
David
24
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json())

var port = 9000;

app.post('/post/data', function(req, res) {
    console.log('receiving data...');
    console.log('body is ',req.body);
    res.send(req.body);
});

// start the server
app.listen(port);
console.log('Server started! At http://localhost:' + port);

Cela vous aidera. Je suppose que vous envoyez le corps en json.

Gautam
la source
J'oublie toujours d'ajouter le bit bodyParser.json () x_x merci!
Jonny Asmar
14

Pour 2019, vous n'avez pas besoin d'installer body-parser.

Vous pouvez utiliser:

var express = require('express');
var app = express();
app.use(express.json())
app.use(express.urlencoded({extended: true}))
app.listen(8888);
app.post('/update', function(req, res) {
    console.log(req.body); // the posted data
});
Shivam Gupta
la source
8

Ceci peut être réalisé sans body-parserdépendance aussi bien, écouter request:dataet request:endet retourner la réponse en fin de requête, reportez - vous ci - dessous exemple de code. réf: https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/#request-body

var express = require('express');
var app = express.createServer(express.logger());

app.post('/', function(request, response) {

    // push the data to body
    var body = [];
    request.on('data', (chunk) => {
      body.push(chunk);
    }).on('end', () => {
      // on end of data, perform necessary action
      body = Buffer.concat(body).toString();
      response.write(request.body.user);
      response.end();
    });
});
Manivannan
la source
3

Essaye ça:

response.write(JSON.stringify(request.body));

Cela prendra l'objet qui bodyParsera créé pour vous et le transformera en une chaîne et l'écrira dans la réponse. Si vous voulez que le corps de la demande exacte (avec le même espacement, etc), vous aurez besoin dataet endauditeurs attachés à la demande avant et construire le morceau de chaîne en morceau que vous pouvez voir dans le code source d'analyse syntaxique JSON de connexion .

Peter Lyons
la source
1

Ce que vous prétendez avoir "essayé de faire" est exactement ce que vous avez écrit dans le code qui fonctionne "comme prévu" lorsque vous l'invoquez avec curl.

L'erreur que vous obtenez ne semble être liée à aucun des codes que vous nous avez montrés.

Si vous souhaitez obtenir la demande brute, les gestionnaires situé sur requestles dataet les endévénements (et, bien sûr, supprimez toutes les invocations de express.bodyParser()). Notez que les dataévénements se produiront par blocs et qu'à moins que vous ne définissiez un codage pour l' dataévénement, ces blocs seront des tampons, pas des chaînes.

ebohlman
la source
c'était une erreur de copier-coller; Je voulais dire request.bodyet non request.body.user, et je l'ai corrigé maintenant. Au fait, var reqBody = request.body;c'était et toujours correct et lorsque vous l'essaierez, vous obtiendrez l'erreur que j'obtiens. Quoi qu'il en soit, pouvez-vous s'il vous plaît donner un exemple sur la configuration du gestionnaire request; Je ne semble pas le trouver dans le guide express.
TheBlueSky
1

Si vous êtes assez paresseux pour lire des morceaux de données de publication. vous pouvez simplement coller sous les lignes pour lire json.

Ci-dessous, pour TypeScript, la même chose peut être faite pour JS.

app.ts

 import bodyParser from "body-parser";
 // support application/json type post data
 this.app.use(bodyParser.json());
 // support application/x-www-form-urlencoded post data
 this.app.use(bodyParser.urlencoded({ extended: false }));

Dans l'un de vos contrôleurs qui reçoivent un appel POST, utilisez comme indiqué ci-dessous

userController.ts

 public async POSTUser(_req: Request, _res: Response) {
   try {
          const onRecord = <UserModel>_req.body;
           /* Your business logic */
           _res.status(201).send("User Created");
        }
    else{
           _res.status(500).send("Server error");
           }        
   };

_req.body devrait analyser vos données json dans votre modèle TS.

Shujaath Khan
la source
1
Je ne sais pas si vous essayez d'encourager ou de décourager les gens d'utiliser votre réponse en les traitant de paresseux :)
TheBlueSky
1

Je suis absolument nouveau dans JS et ES, mais ce qui semble fonctionner pour moi est juste ceci:

JSON.stringify(req.body)

Faites-moi savoir si quelque chose ne va pas!

balintn
la source
exactement ce dont j'avais besoin
Josef Henn
0

Installez Body Parser par la commande ci-dessous

$ npm install --save body-parser

Configurer l'analyseur corporel

const bodyParser = require('body-parser');
app.use(bodyParser);
app.use(bodyParser.json()); //Make sure u have added this line
app.use(bodyParser.urlencoded({ extended: false }));
Arun Abimanyu
la source
-3

Vous utilisez le code suivant pour consigner les données de publication:

router.post("/users",function(req,res){
    res.send(JSON.stringify(req.body, null, 4));
});
Chandra Kumar
la source
2
La réponse donnée est incomplète sans inclure le module d'analyseur de corps.
gramcha