web-dev-qa-db-fra.com

Comment désactiver Express BodyParser pour les téléchargements de fichiers (Node.js)

Cela semble être une question assez simple, mais j'ai beaucoup de mal à comprendre comment l'aborder.

J'utilise Node.js + Express pour créer une application web, et je trouve que le BodyParser de connexion qui exprime est très utile dans la plupart des cas. Cependant, j'aimerais avoir un accès plus granulaire aux POSTS de données de formulaire en plusieurs parties au fur et à mesure qu'ils viennent - j'ai besoin de diriger le flux d'entrée vers un autre serveur, et je veux éviter de télécharger le fichier entier en premier.

Parce que j'utilise Express BodyParser, cependant, tous les téléchargements de fichiers sont analysés automatiquement et téléchargés et disponibles à l'aide de "request.files" avant d'arriver à l'une de mes fonctions.

Existe-t-il un moyen de désactiver le BodyParser pour les publications de données de formulaire en plusieurs parties sans le désactiver pour tout le reste?

58
Myk

Si vous devez utiliser les fonctionnalités fournies par express.bodyParser mais vous voulez le désactiver pour les données en plusieurs parties/formulaires, l'astuce est de ne pas utiliser express.bodyParser directly. express.bodyParser est une méthode pratique qui englobe trois autres méthodes: express.json, express.urlencoded, et express.multipart.

Donc au lieu de dire

app.use(express.bodyParser())

tu as juste besoin de dire

app.use(express.json())
   .use(express.urlencoded())

Cela vous donne tous les avantages du bodyparser pour la plupart des données tout en vous permettant de gérer les téléchargements de données de formulaire indépendamment.

Modifier: json et urlencoded ne sont désormais plus fournis avec Express. Ils sont fournis par le module séparé body-parser et vous les utilisez maintenant comme suit:

bodyParser = require("body-parser")
app.use(bodyParser.json())
   .use(bodyParser.urlencoded())
60
Myk

Si la nécessité d'analyser le corps dépend uniquement de la route elle-même, la chose la plus simple est d'utiliser bodyParser comme fonction de middleware de route uniquement sur les routes qui en ont besoin plutôt que de l'utiliser à l'échelle de l'application:

var express=require('express');
var app=express.createServer();
app.post('/body', express.bodyParser(), function(req, res) {
    res.send(typeof(req.body), {'Content-Type': 'text/plain'});
});
app.post('/nobody', function(req, res) {
    res.send(typeof(req.body), {'Content-Type': 'text/plain'});
});
app.listen(2484);
27
ebohlman

Dans Express 3, vous pouvez passer le paramètre à bodyParser comme {defer: true} - qui, à terme, diffère le traitement en plusieurs parties et expose l'objet Formidable form comme req.form. Cela signifie que votre code peut être:

...
app.use(express.bodyParser({defer: true}));

...
// your upload handling request 
app.post('/upload', function(req, res)) {
    var incomingForm = req.form  // it is Formidable form object

    incomingForm.on('error', function(err){

          console.log(error);  //handle the error

    })

    incomingForm.on('fileBegin', function(name, file){

         // do your things here when upload starts
    })


    incomingForm.on('end', function(){

         // do stuff after file upload
    });

    // Main entry for parsing the files
    // needed to start Formidables activity
    incomingForm.parse(req, function(err, fields, files){


    })
}

Pour une gestion plus détaillée des événements formidables, reportez-vous à https://github.com/felixge/node-formidable

15
alekperos

J'ai rencontré des problèmes similaires dans 3.1.1 et j'ai trouvé (pas si joli IMO) une solution:

pour désactiver bodyParser pour les données en plusieurs parties/formulaires:

var bodyParser = express.bodyParser();
app.use(function(req,res,next){
    if(req.get('content-type').indexOf('multipart/form-data') === 0)return next();
    bodyParser(req,res,next);
});

et pour analyser le contenu:

app.all('/:token?/:collection',function(req,res,next){
    if(req.get('content-type').indexOf('multipart/form-data') !== 0)return next();
    if(req.method != 'POST' && req.method != 'PUT')return next();
    //...use your custom code here
});

par exemple, j'utilise noeud-multipartite où le code personnalisé devrait ressembler à ceci:

    var form = new multiparty.Form();

    form.on('file',function(name,file){
       //...per file event handling
    });     

    form.parse(req, function(err, fields, files) {
       //...next();
    });
4
JakubKnejzlik

Avec express v4 et body-parser v1.17 et supérieur,
Vous pouvez passer une fonction dans le type de bodyParser.json.
body-parser analysera uniquement les entrées où cette fonction renvoie une valeur véridique.

app.use(bodyParser.json({
    type: function(req) {
        return req.get('content-type').indexOf('multipart/form-data') !== 0;
    },
}));

Dans le code ci-dessus,
la fonction renvoie une valeur fausse si le content-type est multipart/form-data.
Ainsi, il n'analyse pas les données lorsque le content-type est multipart/form-data.

2
itch96

jeter c'est avant app.configure

delete express.bodyParser.parse['multipart/form-data'];
1
jwerre