nodejs文件上传处理模块formidable

本文转自http://itbilu.com/nodejs/npm/NkGKcF14.html

 在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原生环境中使用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;
  }
 

 上传后,响应结果如下 
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;

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





猜你喜欢

转载自blog.csdn.net/goodgirl1991/article/details/53407603