NodeJS学习笔记: 简述Express的中间件multer的使用

前言

本人不是技术专家,该笔记只是从使用语言进行开发的层面上记录一些体会,不包含也不想尝试从源码或者更深的层次去讨论语言自己的优劣。文章内容是笔者的我的感悟,既不保证正确性,也不保证别人能看懂。前端

这居然是该笔记的第二篇,虽然不肯定之后会不会有第三篇。git

第一篇在这里:NodeJS学习笔记: require, exports 和 module.exports 的初印象github

引子

事实上我是基于MEANJS框架开始NodeJS的探索的,相对于angularJS而言,服务器端的坑真实太多了,虽然npm上不少模块可使用,可是大部分没有详细的文档,真是毁人不倦啊。
在MEANJS的demo演示中提供了用户头像的功能,本次学习目的是把文件上传功能独立出来。前端的上传处理使用的是angular-file-upload数据库

正文

个人目标是提供一个上传文件的表单,数据库端将会存放以下的数据:express

  1. 文件idnpm

  2. 用户idsegmentfault

  3. URL服务器

  4. MIME-TYPEapp

  5. 文件大小框架

  6. 原始文件名

  7. 标题,若是是图片这个一般用来讲明图片的主题,这里我设置为必填了。

  8. 描述,若是是图片这个放在alt中比较好,可选。

好吧,开始。

前端第一坑:formData

angular-file-uploader提供了formData,可是我尝试了好久这个数据也传送不到个人PHP服务器上。没错,这里我用了PHP,这个我比较熟。

窍门:不少同窗喜欢写完了功能再调试,这其实很是麻烦,
由于中间的任何一步错了都致使结果不对,
我一般对于没有实足把握的步骤都是当即测试的。

解决方案:在其实例的onBeforeUploadItem事件被触发的时候再写入formData,并且要用push防止覆盖原始数据。

uploader.onBeforeUploadItem = function(fileItem) {
      fileItem.formData.push({
        title: $scope.upload.title
      });
    };

前端的一个小细节

若是没有选择要上传的文件,其实例uploader的方法uploadAll()是没法被成功调用的,因此

if (uploader.queue.length) {
          uploader.uploadAll();
      } else {
          //用普通的REST方式提交,仅限于update
      }

multer的使用

终于到正文了。官方支持的文档在这里,超简单。

var multerConfig = {
    dest: './modules/uploads/client/uploads/', // Normal file upload destination path
    limits: {
        fileSize: 10*1024*1024 // Max file size in bytes (10 MB)
    },
    fileFilter: function (req, file, cb) {
        var mimetypes = (['text/*', 'image/*', 'video/*', 'audio/*', 'application/zip']).join(',');
        var testItems = file.mimetype.split('/');
        if ((new RegExp('\\b' + testItems[0] + '/\\*', 'i')).test(mimetypes) || (new RegExp('\\*/' + testItems[1] + '\\b', 'i')).test(mimetypes) || (new RegExp('\\b' + testItems[0] + '/' + testItems[1] + '\\b', 'i')).test(mimetypes)) {
            cb(null, true);
        } else {
            return cb(new Error('Only image, plain text, audio, video and zip format files are allowed!'), false);
        }
    } // fileFilter要在这里声明才行,用instance.fileFilter = funciton(){};是无论用的
};
var upload = multer(multerConfig).single('userUploadFiles');//single是指前端angular-file-uploader指定的用来保存文件内容的字段
//除了single还有fields, array方法,是用来处理多文件上传的,官方文档有,用法大同小异。
//下面是关键了,我一直都取不到自定义的title和description字段,req.body, req.query, req.params都是空的,req.file和req.files是undefined,为何呢?
upload(req, res, function (uploadError) {
    //**在这个时候,req.file才出现**(若是不是用的single方法,那么此时req.files出现),同时title和description也被添加到req.body中
    //好了,后面不用说了,大家懂
    if (uploadError) {
        //错误处理
    } else {
        //正常处理,就是删掉被覆盖的文件稍微麻烦点,但也不是问题。
    }
});

总结

Demo不靠谱,文档太简单,搜索无答案的时候仍是看源码靠谱。因此,同窗们的源码要保持格式,同时易读哦。

相关文章
相关标签/搜索