code

파일 업로드를 위해 Express BodyParser를 비활성화하는 방법 (Node.js)

codestyles 2020. 12. 11. 08:14
반응형

파일 업로드를 위해 Express BodyParser를 비활성화하는 방법 (Node.js)


이것은 상당히 간단한 질문 인 것 같지만, 어떻게 접근해야하는지 알아내는 데 정말 어려움을 겪고 있습니다.

저는 Node.js + Express를 사용하여 웹 응용 프로그램을 구축하고 있으며, express 노출하는 connect BodyParser가 대부분의 경우 매우 유용하다는 것을 알았습니다. 그러나 멀티 파트 양식 데이터 POSTS가 올 때마다 더 세분화 된 액세스 권한을 갖고 싶습니다. 입력 스트림을 다른 서버로 파이프해야하며 먼저 전체 파일을 다운로드하지 않으려 고합니다.

그러나 Express BodyParser를 사용하고 있기 때문에 모든 파일 업로드는 자동으로 구문 분석되고 내 기능에 도달하기 전에 "request.files"를 사용하여 업로드되고 사용할 수 있습니다.

다른 모든 항목에 대해 비활성화하지 않고 다중 파트 양식 데이터 게시물에 대해 BodyParser를 비활성화 할 수있는 방법이 있습니까?


를 입력 app.use(express.bodyParser())하면 거의 각 요청이 bodyParser함수를 거치게 됩니다 (실행될 함수는 Content-Type헤더에 따라 다름 ).

기본적으로 3 개의 헤더가 지원됩니다 (AFAIR). 확실한 소스를 볼 수 있습니다. Content-Type다음과 같이 s에 대한 핸들러를 (재) 정의 할 수 있습니다 .

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

에서 제공하는 기능을 사용해야 express.bodyParser하지만 multipart / form-data에 대해 비활성화하려면 트릭을 사용하지 않는 것이 좋습니다 express.bodyParser directly. express.bodyParser세 가지 다른 방법을 래핑하는 편리한 방법은 다음과 같다 : express.json, express.urlencoded, 및 express.multipart.

그래서 말하는 대신

app.use(express.bodyParser())

당신은 단지 말할 필요가 있습니다

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

이를 통해 대부분의 데이터에 대해 bodyparser의 모든 이점을 제공하는 동시에 formdata 업로드를 독립적으로 처리 할 수 ​​있습니다.

편집 : json 그리고 urlencoded지금 더 이상 Express와 함께 번들로 제공되지 않습니다. 별도의 body-parser 모듈에서 제공하며 이제 다음과 같이 사용합니다.

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

본문 구문 분석이 경로 자체에만 의존하는 경우 가장 간단한 방법은 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);

Express 3 내에서 매개 변수를 bodyParseras에 전달할 수 있습니다. {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참조하십시오.


I've faced similar problems in 3.1.1 and found (not so pretty IMO) solution:

to disable bodyParser for multipart/form-data:

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

and for parsing the content:

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

for example I'm using node-multiparty where the custom code should look like this:

    var form = new multiparty.Form();

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

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

With express v4, and body-parser v1.17 and above,
You can pass a function in the type of bodyParser.json.
body-parser will parse only those inputs where this function returns a truthy value.

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

In the above code,
the function returns a falsy value if the content-type is multipart/form-data.
So, it does not parse the data when the content-type is multipart/form-data.


throw this is before app.configure

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

참고URL : https://stackoverflow.com/questions/11295554/how-to-disable-express-bodyparser-for-file-uploads-node-js

반응형