Myk*_*Myk 59 javascript file-upload connect node.js express
这似乎应该是一个相当简单的问题,但我很难弄清楚如何处理它.
我正在使用Node.js + Express构建一个Web应用程序,我发现表达公开的连接BodyParser在大多数情况下非常有用.但是,我希望对多部分表单数据POSTS进行更细粒度的访问 - 我需要将输入流传输到另一台服务器,并且希望避免首先下载整个文件.
但是,因为我正在使用Express BodyParser,所有文件上传都会自动解析并上传,并且在他们访问我的任何功能之前使用"request.files"可用.
有没有办法让我为多部分formdata帖子禁用BodyParser而不禁用其他所有内容?
Myk*_*Myk 61
如果您需要使用提供的功能,express.bodyParser但想要为multipart/form-data禁用它,那么诀窍是不使用express.bodyParser directly.express.bodyParser是一个封装其它三种方法一个方便的方法:express.json,express.urlencoded,和express.multipart.
所以不要说
app.use(express.bodyParser())
Run Code Online (Sandbox Code Playgroud)
你只需要说
app.use(express.json())
.use(express.urlencoded())
Run Code Online (Sandbox Code Playgroud)
这为大多数数据提供了bodysarser的所有好处,同时允许您独立处理formdata上传.
编辑: json和urlencoded现在不再与快递捆绑在一起.它们由单独的body-parser模块提供,现在您可以按如下方式使用它们:
bodyParser = require("body-parser")
app.use(bodyParser.json())
.use(bodyParser.urlencoded())
Run Code Online (Sandbox Code Playgroud)
ebo*_*man 27
如果对body解析的需求仅取决于路由本身,最简单的方法是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);
Run Code Online (Sandbox Code Playgroud)
Ale*_*kii 17
当您键入时app.use(express.bodyParser()),几乎每个请求都将通过bodyParser函数(将执行哪一个函数取决于Content-Type标题).
默认情况下,支持3个标头(AFAIR).您可以确定来源.您可以(重新)为Content-Types 定义处理程序,如下所示:
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();
}
Run Code Online (Sandbox Code Playgroud)
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);
};
};
Run Code Online (Sandbox Code Playgroud)
还有一些关于原始问题的伪代码:
function disableParserForContentType(req, res, next) {
if (req.contentType in options.contentTypes) {
req._body = true;
next();
}
}
Run Code Online (Sandbox Code Playgroud)
ale*_*ros 15
在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){
})
}
Run Code Online (Sandbox Code Playgroud)
有关更详细的强大事件处理,请参阅https://github.com/felixge/node-formidable
我在 3.1.1 中遇到了类似的问题并找到了(在我看来不太漂亮)解决方案:
禁用 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);
});
Run Code Online (Sandbox Code Playgroud)
并解析内容:
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
});
Run Code Online (Sandbox Code Playgroud)
例如,我正在使用 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();
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
42483 次 |
| 最近记录: |