javascript 如何禁用文件上传的Express BodyParser(Node.js)

rbl8hiat  于 2023-05-12  发布在  Java
关注(0)|答案(7)|浏览(147)

我正在使用Node.js + Express构建一个Web应用程序,我发现express公开的connect BodyParser在大多数情况下都非常有用。但是,我希望能够更细粒度地访问多部分表单数据POSTS--我需要将输入流通过管道传输到另一个服务器,并且希望避免首先下载整个文件。
因为我使用的是Express BodyParser,所以所有文件上传都是自动解析的,并在它们到达我的任何函数之前使用“request.files”上传和可用。
有没有一种方法可以让我禁用多部分表单数据帖子的BodyParser,而不禁用其他所有内容?

dwbf0jvd

dwbf0jvd1#

如果你需要使用express.bodyParser提供的功能,但你想禁用它的multipart/form-data,技巧是不要使用express.bodyParser directlyexpress.bodyParser是一个方便的方法,它封装了三个其他方法:express.jsonexpress.urlencodedexpress.multipart
所以与其说

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())
wwwo4jvm

wwwo4jvm2#

如果对body解析的需求仅取决于路由本身,最简单的方法是只在需要它的路由上使用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);
y53ybaqx

y53ybaqx3#

当您键入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 ed beforeexpress.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();
  }
}
ioekq8ef

ioekq8ef4#

在Express 3中,您可以将参数作为{defer: true}传递给bodyParser-这实际上推迟了多部分处理,并将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

vlf7wbxs

vlf7wbxs5#

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

ajsxfq5m6#

使用express v4和body-parser 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,则该函数返回一个falsy值。
因此,当content-typemultipart/form-data时,它不会解析数据。

wxclj1h5

wxclj1h57#

throw this is before app.configure

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

相关问题