61

これはかなり単純な質問のように思えますが、私はそれにアプローチする方法を理解するのに非常に苦労しています.

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

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

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

4

7 に答える 7

62

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

だから言う代わりに

app.use(express.bodyParser())

あなたはただ言う必要があります

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

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

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

bodyParser = require("body-parser")
app.use(bodyParser.json())
   .use(bodyParser.urlencoded())
于 2012-07-02T15:47:35.707 に答える
27

ボディ解析の必要性がルート自体のみに依存する場合、最も簡単な方法は、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);
于 2012-07-04T00:34:23.627 に答える
18

を入力するapp.use(express.bodyParser())と、ほとんどすべてのリクエストが関数を通過しbodyParserます(どちらが実行されるかはContent-Typeヘッダーによって異なります)。

デフォルトでは、3つのヘッダーがサポートされています(AFAIR)。あなたは確かに情報源を見ることができました。Content-Type次のようなものを使用して、のハンドラーを(再)定義できます。

var express = require('express');
var bodyParser = express.bodyParser;

// redefine handler for Content-Type: multipart/form-data
bodyParser.parse('multipart/form-data') = function(req, options, next) {
  // parse request body your way; example of such action:
  // https://github.com/senchalabs/connect/blob/master/lib/middleware/multipart.js

  // for your needs it will probably be this:
  next();
}


upd。

Express 3で状況が変わったので、作業中のプロジェクトから更新されたコードを共有しています(app.useに編集する必要があります)。 express.bodyParser()

var connectUtils = require('express/node_modules/connect/lib/utils');

/**
 * Parses body and puts it to `request.rawBody`.
 * @param  {Array|String} contentTypes Value(s) of Content-Type header for which
                                       parser will be applied.
 * @return {Function}                  Express Middleware
 */
module.exports = function(contentTypes) {
  contentTypes = Array.isArray(contentTypes) ? contentTypes
                                             : [contentTypes];
  return function (req, res, next) {
    if (req._body)
      return next();

    req.body = req.body || {};

    if (!connectUtils.hasBody(req))
      return next();

    if (-1 === contentTypes.indexOf(req.header('content-type')))
      return next();

    req.setEncoding('utf8');  // Reconsider this line!
    req._body   = true;       // Mark as parsed for other body parsers.
    req.rawBody = '';

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

    req.on('end', next);
  };
};

そして、元の質問に関するいくつかの擬似コード:

function disableParserForContentType(req, res, next) {
  if (req.contentType in options.contentTypes) {
    req._body = true;
    next();
  }
}
于 2012-07-04T15:40:46.403 に答える
15

bodyParserExpress 3 内では、パラメーターをas -に渡すことができます。{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を参照してください。

于 2013-03-27T16:17:51.147 に答える
4

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

たとえば、カスタム コードが次のようになる node-multiparty を使用しています。

    var form = new multiparty.Form();

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

    form.parse(req, function(err, fields, files) {
       //...next();
    });
于 2013-04-09T01:54:31.910 に答える
1

これは app.configure の前にスローします

delete express.bodyParser.parse['multipart/form-data'];
于 2012-07-04T05:11:24.787 に答える