在进行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', ), 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: }, { name: 'gallery', maxCount: }])
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 = * * ;
//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(, {'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(, {'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();

五、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 = * * ;
//form.maxFields = 1000; 设置所以文件的大小总和 form.parse(req, function(err, fields, files) {
res.writeHead(, {'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(, {'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();

参考资料:

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

node+express实现文件上传功能的更多相关文章

  1. node express formidable 文件上传后修改文件名

    //我是用php的思想来学习nodejs var express = require('express'); var router = express.Router(); var fs = requi ...

  2. Vue+axios+Node+express实现文件上传(用户头像上传)

    Vue 页面的代码 <label for='my_file' class="theme-color"> <mu-icon left value="bac ...

  3. Node.js新手教程——怎样实现文件上传功能

    作者:zhanhailiang 日期:2014-11-16 本文将介绍怎样使用Node.js实现文件上传功能. 1. 初始化项目信息:npm init [root@~/wade/nodejs/node ...

  4. Node.js 博客实例(三)添加文件上传功能

    原教程 https://github.com/nswbmw/N-blog/wiki/_pages的第三章 上传文件眼下有三种方法: 使用 Express 自带的文件上传功能,不涉及数据库 使用 For ...

  5. nodejs 实现简单的文件上传功能

    首先需要大家看一下目录结构,然后开始一点开始我们的小demo. 文件上传总计分为三种方式: 1.通过flash,activeX等第三方插件实现文件上传功能. 2.通过html的form标签实现文件上传 ...

  6. node中间层实现文件上传

    一般情况下,前端的文件上传一般都是通过form表单的(<input type="file" />)来完成文件的上传,如果使用node中间层完成跨域,文件的上传就需要在n ...

  7. PHPCMS_V9 模型字段添加单文件上传功能

    后台有“多文件上传”功能,但是对于有些情况,我们只需要上传一个文件,而使用多文件上传功能上传一个文件,而调用时调用一个文件URL太麻烦了. 使用说明: 1.打开phpcms\modules\conte ...

  8. 配置php.ini实现PHP文件上传功能

    本文介绍了如何配置php.ini实现PHP文件上传功能.其中涉及到php.ini配置文件中的upload_tmp_dir.upload_max_filesize.post_max_size等选项,这些 ...

  9. MVC5:使用Ajax和HTML5实现文件上传功能

    引言 在实际编程中,经常遇到实现文件上传并显示上传进度的功能,基于此目的,本文就为大家介绍不使用flash 或任何上传文件的插件来实现带有进度显示的文件上传功能. 基本功能:实现带有进度条的文件上传功 ...

随机推荐

  1. 如何构建高性能MySQL索引

    本文的重点在于如何构建一个高性能的MySQL索引,从中你可以学到如何分析一个索引是不是好索引,以及如何构建一个好的索引. 索引误区 多列索引 一个索引的常见误区是为每一列创建一个索引,如下面创建的索引 ...

  2. SSM框架面试题及答案整理

    一.Spring面试题 1.Spring 在ssm中起什么作用? Spring:轻量级框架 作用:Bean工厂,用来管理Bean的生命周期和框架集成. 两大核心:①. IOC/DI(控制反转/依赖注入 ...

  3. Java高级面试题及答案

    List和Set比较,各自的子类比较 对比一:Arraylist与LinkedList的比较 1.ArrayList是实现了基于动态数组的数据结构,因为地址连续,一旦数据存储好了,查询操作效率会比较高 ...

  4. MathType怎么编辑半开半闭区间

    数学中的公式有很多,涉及到各种各样的样式,这些公式都会用到不同的符号,每一个符号用在不同数学问题的公式中,都会有其特定的意义,比如括号.括号这个符号在除了能够表示优先运算之外,还可以代表区间的意思,小 ...

  5. Mongodb安全认证

    Mongodb安全认证在单实例和副本集两种情况下不太一样,单实例相对简单,只要在启动时加上 --auth参数即可,但副本集则需要keyfile. 一.单实例 1.启动服务(先不要加auth参数) 2. ...

  6. python打造线程池

    # coding=utf-8 import threading import Queue import time import traceback class ThreadPoolExecutor(o ...

  7. Oauth2.0(五):Authorization Code 授权

    Authorization Code 方式适用于有自己的服务器的应用.之所以叫这个名字,是因为流程中引入了一个叫做 authorization code 的东西.这个东西是一个一次性的临时凭证,用来换 ...

  8. 浅谈Java的学习

    Java就是用来做项目的!Java的主要应用领域就是企业级的项目开发!要想从事企业级的项目开发,你必须掌握如下要点: 1.掌握项目开发的基本步骤2.具备极强的面向对象的分析与设计技巧3.掌握用例驱动. ...

  9. c 编译和链接过程

    详解link  有 些人写C/C++(以下假定为C++)程序,对unresolved external link或者duplicated external simbol的错误信息不知所措(因为这样的错 ...

  10. GSAP JS基础教程--TweenLite操作元素的相关属性

    今天来学习用TweenLite操作元素的各种属性,以Div为例,其他元素的操作也是一样的,只是可能一些元素有它们的特殊属性,就可能不同罢了.   代码里用详细注释,我就不再重复啦,大家看代码就可以啦! ...