113 votes

Node.js - obtenir le corps brut de la requête en utilisant Express

Lorsque j'utilise Express, et que mon code est :

app.use(express.bodyParser());

Comment puis-je obtenir le corps brut de la demande ?

110voto

hexacyanide Points 15723

Edit 2 : La version 1.15.2 du module body parser introduit mode brut qui renvoie le corps sous la forme d'un Tampon . Par défaut, il gère aussi automatiquement la décompression deflate et gzip. Exemple d'utilisation :

var bodyParser = require('body-parser');
app.use(bodyParser.raw(options));

app.get(path, function(req, res) {
  // req.body is a Buffer object
});

Par défaut, le options a les options par défaut suivantes :

var options = {
  inflate: true,
  limit: '100kb',
  type: 'application/octet-stream'
};

Si vous voulez que votre analyseur brut analyse d'autres types MIME autres que application/octet-stream vous devrez le modifier ici. Il prendra également en charge la correspondance avec les caractères génériques tels que */* o */application .


Nota: La réponse suivante concerne les versions antérieures à Express 4, où le middleware était encore fourni avec le framework. L'équivalent moderne est le analyseur de corps qui doit être installé séparément.

Le site rawBody dans Express était autrefois disponible, mais elle a été supprimée depuis la version 1.5.1. Pour obtenir le corps brut de la requête, vous devez mettre en place un intergiciel avant d'utiliser le bodyParser. Vous pouvez également lire une discussion GitHub à ce sujet aquí .

app.use(function(req, res, next) {
  req.rawBody = '';
  req.setEncoding('utf8');

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

  req.on('end', function() {
    next();
  });
});
app.use(express.bodyParser());

Ce logiciel intermédiaire lira le flux de données réel et le stockera dans le fichier rawBody de la demande. Vous pouvez alors accéder au corps brut comme ceci :

app.post('/', function(req, res) {
  // do something with req.rawBody
  // use req.body for the parsed body
});

Edit : Il semble que cette méthode et bodyParser refusent de coexister, car l'une d'entre elles consommera le flux de requêtes avant l'autre, ce qui fait que celle qui est en deuxième position ne déclenchera jamais la méthode end et n'appelle donc jamais next() et accrocher votre candidature.

La solution la plus simple serait probablement de modifier le source de bodyParser, que vous trouverez sur ligne 57 de l'analyseur JSON de Connect. Voici à quoi ressemblerait la version modifiée.

var buf = '';
req.setEncoding('utf8');
req.on('data', function(chunk){ buf += chunk });
req.on('end', function() {
  req.rawBody = buf;
  var first = buf.trim()[0];
  ...
});

Vous trouverez le fichier à cet endroit :

/node_modules/express/node_modules/connect/lib/middleware/json.js .

57voto

Tiago A. Points 2310

J'ai trouvé une solution qui fonctionne bien avec le bodyParser, en utilisant la fonction verify callback dans bodyParser. Dans ce code, je l'utilise pour obtenir un sha1 du contenu et aussi pour obtenir le corps brut.

app.use(bodyParser.json({
    verify: function(req, res, buf, encoding) {

        // sha1 content
        var hash = crypto.createHash('sha1');
        hash.update(buf);
        req.hasha = hash.digest('hex');
        console.log("hash", req.hasha);

        // get rawBody        
        req.rawBody = buf.toString();
        console.log("rawBody", req.rawBody);

    }
}));

Je suis nouveau dans Node.js et express.js (j'ai commencé hier, littéralement !) donc j'aimerais entendre des commentaires sur cette solution.

49voto

Pavel Evstigneev Points 477

Cette solution a fonctionné pour moi :

var rawBodySaver = function (req, res, buf, encoding) {
  if (buf && buf.length) {
    req.rawBody = buf.toString(encoding || 'utf8');
  }
}

app.use(bodyParser.json({ verify: rawBodySaver }));
app.use(bodyParser.urlencoded({ verify: rawBodySaver, extended: true }));
app.use(bodyParser.raw({ verify: rawBodySaver, type: '*/*' }));

Lorsque j'utilise la solution avec req.on('data', function(chunk) { }); il ne fonctionne pas sur le corps de la demande en morceaux.

31voto

nortron Points 3267

SOYEZ PRUDENT avec ces autres réponses car elles ne fonctionneront pas correctement avec bodyParser si vous cherchez à supporter également json, urlencoded, etc. Pour qu'il fonctionne avec bodyParser, vous devez conditionner votre gestionnaire pour qu'il ne s'enregistre que sur la balise Content-Type les en-têtes qui vous intéressent, tout comme le fait bodyParser lui-même.

Pour obtenir le contenu brut du corps d'une requête avec l'option Content-Type: "text/plain" en req.rawBody vous pouvez faire :

app.use(function(req, res, next) {
  var contentType = req.headers['content-type'] || ''
    , mime = contentType.split(';')[0];

  if (mime != 'text/plain') {
    return next();
  }

  var data = '';
  req.setEncoding('utf8');
  req.on('data', function(chunk) {
    data += chunk;
  });
  req.on('end', function() {
    req.rawBody = data;
    next();
  });
});

17voto

Nisharg Shah Points 2676

En 2022

La meilleure façon d'obtenir raw body dans chaque API est de convertir le tampon en une chaîne de caractères.

enter image description here

app.use(
  express.json({
    limit: '5mb',
    verify: (req, res, buf) => {
      req.rawBody = buf.toString();
    },
  })
);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X