这个系列文章是自己在开发过程中,自己感悟学习以及借鉴各方大师大神经验分享,非常尊重每个人的劳动成果,目的就是与大家共同分享学习,共同进步!
后台资源管理,增删改查操作必不可少,其中增加资源又是一切的根本,增加的资源的方式有很多种,
1.上传文件 2.复制链接 3.库存导入 4.其他
那今天要和大家要和大家分享的就是最主动地,最基础的方式,自主上传内容这种形式。今天要介绍的方法有三种,留个悬念,开始吧。
一、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
1.application/x-www-form-urlencoded是默认值,作用是设置表单传输的编码。
例如我们在AJAX中见过 xmlHttp.setRequestHeader("Content-Type","application/x-www-form- urlencoded");如果不写会报错的,但是在html的form表单里是可以不写enctype=application/x-www- form-urlencoded,因为默认的HTML表单就是这种传输编码类型的。
2.multipart/form-data是用来制定传输数据的特殊类型的,主要就是我们上传的非文本的内容,比如图片或是是mp3等等。
3.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 }) })
四、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-formidablehttps://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) {//其中files中包含 File对象,是一个h5的新数据类型,可参考w3c File api。这块我踩了很久的坑 res.writeHead(200, {'content-type': 'text/plain'}); res.write('服务器收到了'); 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 FIle模块的详细说明见下