如何禁用文件上传的 Express BodyParser (Node.js)
How to disable Express BodyParser for file uploads (Node.js)
我正在使用Node.js + Express来构建Web应用程序,我发现Express Exposed的连接BodyParser在大多数情况下非常有用。但是,我希望在多部分表单数据 POSTS 出现时能够更精细地访问它们 - 我需要将输入流通过管道传输到另一台服务器,并希望避免先下载整个文件。
但是,因为我使用的是Express BodyParser,所以所有文件上传都会自动解析并使用"request.files"进行上传和访问,然后再访问我的任何函数。
有没有办法让我禁用多部分表单数据帖子的 BodyParser 而不禁用其他所有内容?
如果您需要使用express.bodyParser
提供的功能,但您想为多部分/表单数据禁用它,诀窍是不要使用 express.bodyParser directly
. express.bodyParser
是一种方便的方法,它包装了其他三种方法:express.json
、express.urlencoded
和express.multipart
。
所以与其说
app.use(express.bodyParser())
你只需要说
app.use(express.json())
.use(express.urlencoded())
这为您提供了大多数数据的正文解析器的所有好处,同时允许您独立处理表单数据上传。
编辑:json
和urlencoded
现在不再与Express捆绑在一起。它们由单独的正文解析器模块提供,您现在按如下方式使用它们:
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);
当你键入 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();
}
上。
Express 3 中的情况发生了变化,所以我正在分享工作项目中更新的代码(应该在express.bodyParser()
之前app.use
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 3中,您可以将参数作为{defer: true}
传递给bodyParser
- 这实际上延迟了多部分处理,并将Formidable form对象公开为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
我在 3.1.1 中遇到了类似的问题,并找到了(不太漂亮的 IMO)解决方案:
要禁用多部分/表单数据的正文解析器:
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();
});
使用 express v4 和 body-parser v1.17 及更高版本,
你可以在bodyParser.json的type
中传递一个函数。
正文解析器将仅解析此函数返回真实值的输入。
app.use(bodyParser.json({
type: function(req) {
return req.get('content-type').indexOf('multipart/form-data') !== 0;
},
}));
在上面的代码中,
如果content-type
multipart/form-data
,则该函数返回一个 falsy 值。
因此,当content-type
multipart/form-data
时,它不会解析数据。
在app.config之前抛出这个
delete express.bodyParser.parse['multipart/form-data'];
- Node.js v6.2.0类扩展不是函数错误
- 如何使用 node.js 比较两个 json 数组
- Node.js's Buffer.writeFloatBE in Javascript
- node.js:setInterval()正在跳过调用
- 如何处理node.js节点mongodb中的连接和查询队列
- Node.js正在更改应用程序以使用集群模块
- 如何使用Node.js最有效地解析网页
- 在openshift node js应用程序中获取请求
- 正在删除node.js中已验证的网站
- 与运行长作业(javascript,node.js)的第三方API同步的最佳实践
- 在索引.html和应用.js [node.js] 之间共享变量
- Node.js中的JavaScript原型对象效率
- 如何在构建node-webkit应用程序后获取外部资源
- node.js请求数据事件未在CORS ajax调用中触发
- 使用node.js制作网站
- Node, BodyParser bad json
- 如何禁用文件上传的 Express BodyParser (Node.js)
- 如何在express.bodyParser()和response.write()中使用node
- Node js:同时使用Handlebars和Bodyparser
- 我怎么能正确地发送对象通过AJAX使用bodyParser在node.js express