GITHUB: https://github.com/felixge/node-formidable
在web开发中,经常遇到处理文件上传的情况。而express框架在4.0版本后就不在支持req.files接收上传文件,对于文件上传,需要加multipart格式数据处理的中间件。multipart数据处理中间件有:busboy, multer, formidable, multiparty,connect-multiparty, pez等。本站使用了formidable插件,比较简单易用。
formidable是一个用于处理文件、图片、视频等数据上传的模块,支持GB级上传数据处理,支持多种客户端数据提交。有极高的测试覆盖率,非常适合在生产环境中使用。
安装
formidable是一个轻量级的应用包,可以不依赖于express等框架单独使用,也可以集成到exress框架中使用。安装命令如下:
npm install formidable@latest
在nodejs原生环境中使用,需要手动下载模块后使用
git clone git://github.com/felixge/node-formidable.git formidable vim my.js # var formidable = require('./formidable');
使用
在nodejs原生环境中使用formidable。
var formidable = require('formidable'), http = require('http'), util = require('util'); //用http模块创建一个http服务端 http.createServer(function(req, res) { if (req.url == '/upload' && req.method.toLowerCase() === 'post') { // 处理上传的文件 var form = new formidable.IncomingForm(); form.parse(req, function(err, fields, files) { res.writeHead(200, {'content-type': 'text/plain'}); res.write('received upload:\n\n'); res.end(util.inspect({fields: fields, files: files})); }); return; } //显示一个用于上传的form res.writeHead(200, {'content-type': 'text/html'}); res.end( '<form action="/upload" enctype="multipart/form-data" method="post">'+ '<input type="text" name="title" /> '+ '<input type="file" name="upload" multiple="multiple" /> '+ '<input type="submit" value="Upload" />'+ '</form>' ); }).listen(8080);
上传后,响应结果如下
received upload: { fields: { title: 'title的内容' }, files: //所有type="file"类型的数据对象 { upload: { domain: null, _events: {}, _maxListeners: 10, size: 41966, //文件大小 path: '/var/folders/1k/86kq55_n4_q2tckwz9mb5wyr0000gn/T/upload_ecbf965abc1e14c2ffc86875c2f5eaa8', //文件保存路径 name: 'avatar.jpg', //上传前的文件名 type: 'image/jpeg', //文件类型 hash: null, lastModifiedDate: Sat May 16 2015 10:38:57 GMT+0800 (CST), _writeStream: [Object] } } }
常用API
创建一个incoming form实例
var form = new formidable.IncomingForm()
设置incoming form fields(fileds指除type=”file”外的其它接收数据)编码
form.encoding = 'utf-8';
设置文件接收后保存的文件夹。此文件夹一般为上传后的临时文件夹,上传后调用 fs.rename()对文件进行移动及重命名。默认保存路径为os.tmpDir()
form.uploadDir = "/my/dir";
设置上传后文件是否使用原扩展名,默认值为false。如果希望保存到form.uploadDir中的文件使用原扩展名时,需要将此项设置为true
form.keepExtensions = false;
‘multipart’或’urlencoded’类型的请求在formidable都支持,可通过上传文件的type属性查看文件类型
form.type
设置上传文件的大小,默认值为2M
form.maxFieldsSize = 2 * 1024 * 1024;
设置最大可接收字段数,用于防止内存溢出,默认值为1000
form.maxFields = 1000;
是否对上传文件进行hash较验,可设置为’sha1′ 或 ‘md5’
form.hash = false;
以上为常用的api,详细使用请参考其github:formidable
在express中使用formidable。
在express框架中使用formidable,需要一个接收文件提交的路由。以下示例为一个接收用户头像提交的路由
router.post("/user/avatar", user.avatar);
路由对应的接收提交数据的方法
//设置头像 exports.avatar = function(req, res, next) { var form = new formidable.IncomingForm(); form.uploadDir = path.join(__dirname, 'tmp'); //文件保存的临时目录为当前项目下的tmp文件夹 form.maxFieldsSize = 1 * 1024 * 1024; //用户头像大小限制为最大1M form.keepExtensions = true; //使用文件的原扩展名 form.parse(req, function (err, fields, file) { var filePath = ''; //如果提交文件的form中将上传文件的input名设置为tmpFile,就从tmpFile中取上传文件。否则取for in循环第一个上传的文件。 if(file.tmpFile){ filePath = file.tmpFile.path; } else { for(var key in file){ if( file[key].path && filePath==='' ){ filePath = file[key].path; break; } } } //文件移动的目录文件夹,不存在时创建目标文件夹 var targetDir = path.join(__dirname, 'upload'); if (!fs.existsSync(targetDir)) { fs.mkdir(targetDir); } var fileExt = filePath.substring(filePath.lastIndexOf('.')); //判断文件类型是否允许上传 if (('.jpg.jpeg.png.gif').indexOf(fileExt.toLowerCase()) === -1) { var err = new Error('此文件类型不允许上传'); res.json({code:-1, message:'此文件类型不允许上传'}); } else { //以当前时间戳对上传文件进行重命名 var fileName = new Date().getTime() + fileExt; var targetFile = path.join(targetDir, fileName); //移动文件 fs.rename(filePath, targetFile, function (err) { if (err) { console.info(err); res.json({code:-1, message:'操作失败'}); } else { //上传成功,返回文件的相对路径 var fileUrl = '/upload/' + fileName; res.json({code:0, fileUrl:fileUrl}); } }); process.nextTick(function(){ fs.unlink(filePath, function(err) { if (err) { console.info("删除上传时生成的临时文件失败"); console.info(err); } else { console.info("删除上传时生成的临时文件"); } }); }); } }); }
以上方法数据返回格式为json,客户端接收时可根据情况做相应处理。一个jQuery Ajax客户端上传示例请参考: jQuery文件上传插件jQuery Upload File 有上传进度条
Keep up the good writing.
own weblog and was wondering what all is needed to
get set up? I’m assuming having a blog like yours
would cost a pretty penny? I’m not very web smart so I’m not 100% positive.
Any tips or advice would be greatly appreciated.
Thanks
shocked why this accident didn’t took place in advance!
I bookmarked it.
listen news on TV, therefore I just use the web for that reason, and take the most recent news.
Extremely useful information particularly the last part :
) I care for such info much. I was looking for this particular info for a
very long time. Thank you and good luck.
It seems that you’re doing any distinctive trick. Furthermore, The contents are masterpiece.
you’ve performed a fantastic task on this topic!
after going through many of the posts I realized it’s new to me.
Regardless, I’m definitely delighted I came across it and I’ll be
bookmarking it and checking back often!
regular basis, if so after that you will definitely
obtain fastidious knowledge.
should also go to see this webpage on regular basis to take updated from
newest gossip.
to pay a quick visit the website, that’s what this web site is
providing.