web-dev-qa-db-fra.com

Node.js - Récupère le corps de la requête brute avec Express

Lorsque j'utilise Express, mon code est:

app.use(express.bodyParser());

Comment pourrais-je obtenir le corps de la requête brute?

59
haitao_wu

Edit 2: La version 1.15.2 du module d'analyse de corps introduit mode brut , qui renvoie le corps sous forme de Tampon . Par défaut, il gère également automatiquement les décompressions 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, l'objet options a les options par défaut suivantes:

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

Si vous souhaitez que votre analyseur brut analyse d'autres types MIME autres que application/octet-stream, Vous devrez le changer ici. Il prendra également en charge les correspondances génériques telles que */* Ou */application.


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

La propriété rawBody dans Express était auparavant disponible, mais supprimée depuis la version 1.5.1. Pour obtenir le corps de la demande brute, vous devez mettre un middleware avant d'utiliser bodyParser. Vous pouvez également lire une discussion de GitHub à ce sujet ici .

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 middleware lira le flux de données réel et le stockera dans la propriété 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'un consommera le flux de demandes avant l'autre, conduisant à celui qui est le second à jamais fire end, donc n’appelez jamais next(), et suspendez votre application.

La solution la plus simple serait probablement de modifier la 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 emplacement:

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

67
hexacyanide

J'ai une solution qui joue à Nice avec bodyParser, en utilisant le callback verify 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 (commencé hier, littéralement!), Alors j'aimerais entendre vos commentaires sur cette solution.

38
Tiago A.

SOYEZ PRUDENT avec ces autres réponses, car elles ne joueront pas correctement avec bodyParser si vous souhaitez également prendre en charge json, codage URL, etc. Pour que cela fonctionne avec bodyParser, vous devez conditionner votre gestionnaire à s'enregistrer uniquement sur le Content-Type _ en-tête (s) qui vous tient à cœur, tout comme le fait bodyParser lui-même.

Pour obtenir le contenu du corps brut d'une requête avec Content-Type: "text/plain" dans req.rawBody, vous pouvez effectuer les opérations suivantes:

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();
  });
});
24
nortron

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 requête fragmentée.

21
Pavel Evstigneev

Ceci est une variation de la réponse de l'hexacyanide ci-dessus. Ce middleware gère également l'événement 'data' mais n'attend pas que les données soient consommées avant d'appeler 'next'. De cette façon, ce middleware et bodyParser peuvent coexister, consommant le flux en parallèle.

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

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

  next();
});
app.use(express.bodyParser());
13
oferei

Utilisez body-parser Analyser le corps avec ce qu'il sera:

app.use(bodyParser.text());

app.use(bodyParser.urlencoded());

app.use(bodyParser.raw());

app.use(bodyParser.json());

c'est à dire. Si vous êtes censé obtenir un fichier texte brut, exécutez .text().

C’est ce que l’analyseur de corps supporte actuellement

0
mewc