在進行node web開發時,咱們可能常常遇到上傳文件的問題,這一塊若是咱們沒有經驗,可能會遇到不少坑,下面我將跟你們分享一下,實現文件上傳的一些方式。html
經過一段時間的查閱資料、摸索,我發現實現上傳的方式有:1.express中間件multer模塊(此效率最高,在express3.x原生支持,到了express4.x獨立成一個模塊了),2.connect-multiparty模塊(但如今官方不推薦),3.使用multiparty模塊實現(此方法比較廣泛),4.使用formidable插件實現(插件呢,就是簡單易懂);node
首先知道enctype這個屬性管理的是表單的MIME編碼。共有三個值可選:
一、application/x-www-form-urlencoded
二、multipart/form-data
三、text/plain
其中application/x-www-form-urlencoded是默認值,做用是設置表單傳輸的編碼。例如咱們在AJAX中見過xmlHttp.setRequestHeader("Content-Type","application/x-www-form- urlencoded");若是不寫會報錯的,可是在html的form表單裏是能夠不寫enctype=application/x-www-form-urlencoded,由於默認的HTML表單就是這種傳輸編碼類型的。
而multipart/form-data是用來制定傳輸數據的特殊類型的,主要就是咱們上傳的非文本的內容,好比圖片或是是mp3等等。
text/plain是純文本傳輸的意思,在發郵件的時候要設置這種編碼類型,不然會出現接收時編碼混亂的問題。網絡上常常拿text/plain和 text/html作比較,其實這兩個很好區分,前者用來傳輸純文本文件,後者則是傳遞html代碼的編碼類型,在發送頭文件時才用得上。①和③都不能用於上傳文件,只有multipart/form-data才能完整的傳遞文件數據。git
當咱們採用enctype='multipart/form-data' 會以request payload提交數據,如圖。github
github地址:https://github.com/expressjs/multer https://www.npmjs.com/package/multerweb
Multer是node的一箇中間件,經過multipart/form-data類型提交,若是在頂部寫入busboy模塊(能夠快速解析來自html的數據)能夠加快效率。express
安裝multer:npm
npm install --save multer
官方基本例子:網絡
var express = require('express') var multer = require('multer') var upload = multer({ dest: 'uploads/' }) var app = express() app.post('/profile', upload.single('avatar'), function (req, res, next) { // req.file is the `avatar` file // req.body will hold the text fields, if there were any }) app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) { // req.files is array of `photos` files // req.body will contain the text fields, if there were any }) var cpUpload = upload.fields([{ name: 'avatar', maxCount: 1 }, { name: 'gallery', maxCount: 8 }]) app.post('/cool-profile', cpUpload, function (req, res, next) { // req.files is an object (String -> Array) where fieldname is the key, and the value is array of files // // e.g. // req.files['avatar'][0] -> File // req.files['gallery'] -> Array // // req.body will contain the text fields, if there were any })
也能夠經過:app
var upload = multer({dest:"uploads/"}).single('avatar'); app.post('/profile', function (req, res) { upload(req, res, function (err) { if (err) { console.log(req.body); //打印請求體 console.log(req.file); // An error occurred when uploading return } // Everything went fine }) })
可是,最後咱們有實現成功上傳,用github的例子練過好屢次,都沒有實現成功,但願那位大神幫我指點一下。post
github地址:https://github.com/andrewrk/node-multiparty
使用multiparty模塊,也是必需要使用"multipart/form-data"類型,經過busboy模塊能夠加快解析效率。
安裝multiparty:
npm install multiparty
其實這個也比較簡單:
var multiparty = require('multiparty'); var http = require('http'); var util = require('util'); var fs = require("fs"); http.createServer(function(req, res) { if (req.url === '/upload' && req.method === 'POST') { // 解析一個文件上傳 var form = new multiparty.Form(); //設置編輯 form.encoding = 'utf-8'; //設置文件存儲路徑 form.uploadDir = "uploads/images/"; //設置單文件大小限制 form.maxFilesSize = 2 * 1024 * 1024; //form.maxFields = 1000; 設置因此文件的大小總和 form.parse(req, function(err, fields, files) { console.log(files.originalFilename); console.log(files.path); //同步重命名文件名 fs.renameSync(files.path,files.originalFilename); res.writeHead(200, {'content-type': 'text/plain'}); res.write('received upload:\n\n'); res.end(util.inspect({fields: fields, files: files})); }); return; } // show a file upload form res.writeHead(200, {'content-type': 'text/html'}); res.end( '<form action="/upload" enctype="multipart/form-data" method="post">'+ '<input type="text" name="title"><br>'+ '<input type="file" name="upload" multiple="multiple"><br>'+ '<input type="submit" value="Upload">'+ '</form>' ); }).listen(8080);
formidable上傳插件,也是在github上同類功能人氣比較高的。
github地址: https://github.com/felixge/node-formidable https://www.npmjs.org/package/formidable
優勢:
1. 速度快(~500M/s),沒有non-buffering multipart解析
2.自動寫入到上傳文件磁盤
3.佔用內存低
4.優雅的錯誤處理
5.很是高的測試覆蓋率
formidable安裝:
npm install formidable@latest
官方例子:
var formidable = require('formidable'), http = require('http'), util = require('util'); http.createServer(function(req, res) { if (req.url == '/upload' && req.method.toLowerCase() == 'post') { //建立表單上傳 var form = new formidable.IncomingForm(); //設置編輯 form.encoding = 'utf-8'; //設置文件存儲路徑 form.uploadDir = "uploads/images/"; //保留後綴 form.keepExtensions = true; //設置單文件大小限制 form.maxFieldsSize = 2 * 1024 * 1024; //form.maxFields = 1000; 設置因此文件的大小總和 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; } // show a file upload form res.writeHead(200, {'content-type': 'text/html'}); res.end( '<form action="/upload" enctype="multipart/form-data" method="post">'+ '<input type="text" name="title"><br>'+ '<input type="file" name="upload" multiple="multiple"><br>'+ '<input type="submit" value="Upload">'+ '</form>' ); }).listen(8080);
參考資料:
express中間件multer模塊:https://github.com/expressjs/multer
如用multer解決不了建議用multiparty:https://github.com/andrewrk/node-multiparty
formidable:https://github.com/felixge/node-formidable
https://www.npmjs.org/package/formidable
Node.js學習系列總索引:http://www.cnblogs.com/zhongweiv/p/nodejs.html
node-upload-practice:https://cnodejs.org/topic/5470a385a3e2aee40698de20
node-uuid解決文件名重複問題:https://github.com/broofa/node-uuid