本人不是技術專家,該筆記只是從使用語言進行開發的層面上記錄一些體會,不包含也不想嘗試從源碼或者更深的層次去討論語言自己的優劣。文章內容是筆者的我的感悟,既不保證正確性,也不保證別人能看懂。前端
這居然是該筆記的第二篇,雖然不肯定之後會不會有第三篇。git
第一篇在這裏:NodeJS學習筆記: require, exports 和 module.exports 的初印象github
事實上我是基於MEANJS框架開始NodeJS的探索的,相對於angularJS而言,服務器端的坑真實太多了,雖然npm上不少模塊可使用,可是大部分沒有詳細的文檔,真是毀人不倦啊。
在MEANJS的demo演示中提供了用戶頭像的功能,本次學習目的是把文件上傳功能獨立出來。前端的上傳處理使用的是angular-file-upload。數據庫
個人目標是提供一個上傳文件的表單,數據庫端將會存放以下的數據:express
文件idnpm
用戶idsegmentfault
URL服務器
MIME-TYPEapp
文件大小框架
原始文件名
標題,若是是圖片這個一般用來講明圖片的主題,這裏我設置爲必填了。
描述,若是是圖片這個放在alt中比較好,可選。
好吧,開始。
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 }
終於到正文了。官方支持的文檔在這裏,超簡單。
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不靠譜,文檔太簡單,搜索無答案的時候仍是看源碼靠譜。因此,同窗們的源碼要保持格式,同時易讀哦。