在进行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. opencv获取IP摄像头(IP-camera)实时视频流

    之前这篇文章讲了如何通过网络摄像头(web camera)获取实时视频流,但是这种方法的缺陷就是摄像头和主机必须连在一起,那这种在室外部署的时候就会非常麻烦并且不安全,所以后来找了下用海康威视或者大华 ...

  2. 利用opencv作透明重叠人群密度热度图

    在作热度图的时候我们经常需要将热度图调整透明度后叠加在原图上达到更好的展示效果.比如检测人气密度的热度图: (来自sensetime) 一般作图的时候会第一时间想到matplotlib,因为可以很方便 ...

  3. MySQL索引优化入门

    索引简介 官方定义:索引(Index) 是帮助MySQL高效获取数据的数据结构.大家一定很好奇,索引为什么是一种数据结构,它又是怎么提高查询的速度?我们拿最常用的二叉树来分析索引的工作原理.看下面的图 ...

  4. mysql中json_merge函数的使用?

    需求描述: 通过mysql中的json_merge函数,可以将多个json对象合并成一个对象 操作过程: 1.查看一张包含json列的表 mysql> select * from tab_jso ...

  5. Jackson Gson Json.simple part 2

    这篇blog介绍 Jackson 的特点和使用方法 Jackson支持三种使用方法 流API(streaming api Incremental parsing/generation) JsonPar ...

  6. Centos6.3 下使用 Tomcat-6.0.43 非root用户 部署 生产环境 端口转发方式

    一.安装JDK环境 方法一. 官方下载链接 http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260 ...

  7. mysql字段集合中如何去除其中一个元素

    在一对多方案中,我们用逗号拼接进行存储,避免存储多条,或者分表,那么此时出现了存储上如果需要修改的话 就带来了难度,比如规则记录表如下 如果2号规则被删除,那么这张表的所有有2的记录也要被清除掉,此时 ...

  8. 品鉴同事发来的炸金花的PHP程序代码

    今天同事发来了一个炸金花的PHP程序,这个代码实现了两个人通过各自的三张牌进行权重计算,得到分数进行比较得到谁的牌大,我觉得里面还有一些问题,代码如下: <?php /** 每张牌的分值为一个2 ...

  9. DNS原理入门

    原文链接:http://www.ruanyifeng.com/blog/2016/06/dns.html http://www.ruanyifeng.com/blog/2012/05/internet ...

  10. UnicodeEncodeError: ‘gbk’ codec can’t encode character u’\u200e’ in position 43: illegal multib

    [问题] 在执行代码时,提示上述错误,源码如下: # 下载小说... def download_stoy(crawl_list,header): # 创建文件流,将各个章节读入内存 with open ...