如何禁用快速BodyParser文件上传(Node.js的)如何禁用快速BodyParser文件上传

2019-06-14 11:35发布

这似乎应该是一个相当简单的问题,但我有一个很艰难的时间搞清楚如何对待它。

我如何使用Node.js + Express来构建Web应用程序,而且我发现,表达对暴露在大多数情况下是非常有用的连接BodyParser。 不过,我想有到多格式数据的帖子更细粒度的访问,因为他们来 - 我需要管的输入流到另一台服务器,并要避免先下载整个文件。

因为我使用的快递BodyParser,但是,所有文件上传自动解析和使用“request.files”,他们曾经得到我的任何功能之前上传的和可用的。

有我的方式来禁用BodyParser为多FORMDATA职位没有禁用它的一切?

Answer 1:

当键入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。

事情已经在快递3处更改,所以我共享更新的代码工作项目(应该是app.use ED 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();
  }
}


Answer 2:

如果您需要使用所提供的功能express.bodyParser但要禁用它的multipart / form-data的,关键是不使用express.bodyParser directlyexpress.bodyParser是一个封装其它三种方法一个方便的方法: express.jsonexpress.urlencoded ,和express.multipart

所以不是说

app.use(express.bodyParser())

你只需要说

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

这使您bodyparser大多数数据的所有优点,同时还可以独立处理FORMDATA上传。

编辑: jsonurlencoded ,现在不再使用Express捆绑在一起。 它们由独立提供身体解析器模块,你现在按如下方式使用它们:

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


Answer 3:

如果需要对身体解析只取决于路由本身,最简单的就是用bodyParser只需要它,而不是使用它APP-广泛的路由作为路由中间件功能:

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


Answer 4:

在快递3,你可以传递参数给bodyParser{defer: true} -这在长期推迟多处理,并公开了强大的表单对象为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



Answer 5:

我面临类似的问题在3.1.1和发现(不那么漂亮IMO)的解决方案:

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


Answer 6:

随着快递V4和身体分析器V1.17及以上,
您可以在传递一个函数type bodyParser.json的。
体分析器将解析仅在此函数返回一个值truthy那些输入。

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

在上面的代码,
如果该函数返回一个值falsy content-typemultipart/form-data
所以,当它不分析数据content-typemultipart/form-data



Answer 7:

抛出这个是app.configure前

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


文章来源: How to disable Express BodyParser for file uploads (Node.js)