node+express實現文件上傳功能

jopen 9年前發布 | 216K 次閱讀 Node.js 開發 Node

 

在進行node web開發時,我們可能經常遇到上傳文件的問題,這一塊如果我們沒有經驗,可能會遇到很多坑,下面我將跟大家分享一下,實現文件上傳的一些方式。

一、node+express文件上傳的常用方式

通過一段時間的查閱資料、摸索,我發現實現上傳的方式有:1.express中間件multer模塊(此效率最高,在express3.x原生支持,到了express4.x獨立成一個模塊了),2.connect-multiparty模塊(但現在 官方不推薦 ),3.使用multiparty模塊實現(此方法比較普遍),4.使用formidable插件實現(插件呢,就是簡單易懂);

二、了解multipart/form-data

首先知道enctype這個屬性管理的是表單的MIME編碼。共有三個值可選:

1、application/x-www-form-urlencoded

2、multipart/form-data

3、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才能完整的傳遞文件數據。

當我們采用enctype='multipart/form-data' 會以request payload提交數據,如圖。

三、multer模塊上傳問題

github地址: https://github.com/expressjs/multer  https://www.npmjs.com/package/multer

Multer是node的一個中間件,通過multipart/form-data類型提交,如果在頂部寫入busboy模塊(可以快速解析來自html的數據)可以加快效率。

安裝multer:

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

也可以通過:
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的例子練過好多次,都沒有實現成功,希望那位大神幫我指點一下。

四、multiparty模塊上傳問題

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模塊上傳問題

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

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!