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不靠譜,文檔太簡單,搜索無答案的時候仍是看源碼靠譜。因此,同窗們的源碼要保持格式,同時易讀哦。

相關文章
相關標籤/搜索