web-dev-qa-db-ja.com

ファイルのアップロードでExpress BodyParserを無効にする方法(Node.js)

これはかなり単純な質問のように思えますが、どのようにアプローチするかを考えるのは本当に大変です。

私はNode.js + Expressを使用してWebアプリケーションを構築していますが、ほとんどの場合、エクスポーズを公開する接続BodyParserは非常に便利です。ただし、マルチパートフォームデータのPOSTSへのより詳細なアクセスが必要になります。入力ストリームを別のサーバーにパイプする必要があり、最初にファイル全体をダウンロードしないようにします。

しかし、私はExpress BodyParserを使用しているため、すべてのファイルのアップロードは自動的に解析され、「request.files」を使用してアップロードされてから使用可能になります。

マルチパートフォームデータの投稿でBodyParserを無効にする方法はありますか?

58
Myk

express.bodyParserで提供される機能を使用する必要があるが、multipart/form-dataに対して無効にする場合、express.bodyParser directlyを使用しないことが秘trickです。 express.bodyParserは、express.jsonexpress.urlencoded、およびexpress.multipartの3つの他のメソッドをラップする便利なメソッドです。

と言う代わりに

app.use(express.bodyParser())

あなたは言うだけです

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

これにより、ほとんどのデータに対してbodyparserのすべての利点が得られると同時に、フォームデータのアップロードを個別に処理できます。

編集:jsonurlencodedは、Expressにバンドルされなくなりました。これらは個別の body-parser モジュールによって提供され、次のように使用します。

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

ボディ解析の必要性がルート自体にのみ依存する場合、最も簡単なことは、アプリ全体で使用するのではなく、必要なルートのみでルートミドルウェア関数としてbodyParserを使用することです。

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

Express 3では、パラメーターをbodyParser{defer: true}として渡すことができます。これは、用語でマルチパート処理を遅らせ、Formidableフォームオブジェクトをreq.formとして公開します。コードの意味は次のとおりです。

...
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){


    })
}

恐ろしいイベント処理の詳細については、 https://github.com/felixge/node-formidable を参照してください。

15
alekperos

私は3.1.1で同様の問題に直面し、解決策を見つけました(それほどIMOではありません):

multipart/form-dataのbodyParserを無効にするには:

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);
});

そしてコンテンツを解析するため:

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
});

たとえば、カスタムコードが次のように見えるノードマルチパーティを使用しています。

    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

Express v4、およびボディパーサーv1.17以降では、
bodyParser.jsonのtypeに関数を渡すことができます。
body-parserは、この関数が真理値を返す入力のみを解析します。

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

上記のコードでは、
この関数は、content-typemultipart/form-data
したがって、content-typemultipart/form-data

2
itch96

これはapp.configureの前に投げます

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