目录

前言

  前面讲了一个构建网站的示例,这次在此基础上再说说web的常规功能----文件上传,示例以一个上传图片的功能为例子

  上传功能命名用formidable实现,示例很简单!

  PS:最近比较忙,距上一次更新已经比较久了^_^!

formidable简介

  nodejs原生实现上传还是比较麻烦,有兴趣的自已去参考一下网上有网友写的代码

  这里选择了formidable,也是github上同类功能模块人气比较高的

  https://github.com/felixge/node-formidable

  https://www.npmjs.org/package/formidable

  

  优点:上传速度比较可观,占用内存也比较低,简单易用...

创建项目安装formidable

   1.创建项目sampleUpload

cd 工作目录

express -e sampleUpload

  2.修改package.json文件,添加formidable依赖项

{
  "name": "application-name",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "express": "~4.0.0",
    "static-favicon": "~1.0.0",
    "morgan": "~1.0.0",
    "cookie-parser": "~1.0.1",
    "body-parser": "~1.0.0",
    "debug": "~0.7.4",
    "ejs": "~0.8.5",
    "formidable" : "latest"
  }
}

  3.安装依赖项

cd sampleUpload && npm install

  

  安装成功,一切准备就绪,开始完成这个功能!

实现上传功能

  1.index.ejs文件中构建表单并实现前端验证(样式使用和http://www.cnblogs.com/zhongweiv/p/nodejs_express_webapp.html 一致)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><%= title %></title>

      <link rel="stylesheet" type="text/css" href="/stylesheets/bootstrap.min.css" />
    <link rel="stylesheet" type="text/css" href="/stylesheets/signin.css" />
  </head>

  <body>

    <div id="container" class="container">
       <% if (locals.success) { %>
          <div id="alt_sucess" class="alert alert-success">
            <%- success %>
          </div>
       <% } %> 

      <% if (locals.error) { %>
        <div id="alt_warning" class="alert alert-warning">
          <%= error %>
        </div>
      <% } %> 

      <form class="form-signin" role="form" method="post" enctype='multipart/form-data'>
        <h2 class="form-signin-heading">上传文件</h2>
        <input id="fulAvatar" name="fulAvatar" type="file" class="form-control" />
        <br/>
        <button id="btnSub" class="btn btn-lg btn-primary" type="submit">上 传</button>
      </form>

    </div>
  </body>
</html>

<script src="/javascripts/jquery-1.11.1.min.js" type="text/javascript"></script>

<script type="text/javascript">
     String.prototype.format = function (args) {
            var result = this;
            if (arguments.length > 0) {
                if (arguments.length == 1 && typeof (args) == "object") {
                    for (var key in args) {
                        if (args[key] != undefined) {
                            var reg = new RegExp("({" + key + "})", "g");
                            result = result.replace(reg, args[key]);
                        }
                    }
                }
                else {
                    for (var i = 0; i < arguments.length; i++) {
                        if (arguments[i] != undefined) {
                            var reg = new RegExp("({)" + i + "(})", "g");
                            result = result.replace(reg, arguments[i]);
                        }
                    }
                }
            }
            return result;
    }

    $(function(){
        $('#btnSub').on('click',function(){
            var fulAvatarVal = $('#fulAvatar').val(),
                errorTip = '<div id="errorTip" class="alert alert-warning">{0}</div> ';  

            $("#errorTip,#alt_warning").remove();

            if(fulAvatarVal.length == 0)
            {
                $("#container").prepend(errorTip.format('请选择要上传的文件'));
                return false;
            }

           var extName = fulAvatarVal.substring(fulAvatarVal.lastIndexOf('.'),fulAvatarVal.length).toLowerCase();

            if(extName != '.png' && extName != '.jpg'){
               $("#container").prepend(errorTip.format('只支持png和jpg格式图片'));
               return false;
            }

            return true;
        })
    });

</script>

  这里一定要注意表单的enctype属性,这个就不多作解释了,如果是初次接触,看看http://www.w3school.com.cn/tags/att_form_enctype.asp

  

  2.实现index.js中上传逻辑

var express = require('express')
    router = express.Router(),
    formidable = require('formidable'),
      fs = require('fs'),
      TITLE = 'formidable上传示例',
    AVATAR_UPLOAD_FOLDER = '/avatar/'

/* GET home page. */
router.get('/', function(req, res) {
  res.render('index', { title: TITLE });
});

router.post('/', function(req, res) {

  var form = new formidable.IncomingForm();   //创建上传表单
      form.encoding = 'utf-8';        //设置编辑
      form.uploadDir = 'public' + AVATAR_UPLOAD_FOLDER;     //设置上传目录
      form.keepExtensions = true;     //保留后缀
      form.maxFieldsSize = 2 * 1024 * 1024;   //文件大小

    form.parse(req, function(err, fields, files) {

        if (err) {
          res.locals.error = err;
          res.render('index', { title: TITLE });
          return;
        }  

        var extName = '';  //后缀名
        switch (files.fulAvatar.type) {
            case 'image/pjpeg':
                extName = 'jpg';
                break;
            case 'image/jpeg':
                extName = 'jpg';
                break;
            case 'image/png':
                extName = 'png';
                break;
            case 'image/x-png':
                extName = 'png';
                break;
        }

        if(extName.length == 0){
              res.locals.error = '只支持png和jpg格式图片';
              res.render('index', { title: TITLE });
              return;
        }

        var avatarName = Math.random() + '.' + extName;
        var newPath = form.uploadDir + avatarName;

        console.log(newPath);
        fs.renameSync(files.fulAvatar.path, newPath);  //重命名
    });

    res.locals.success = '上传成功';
    res.render('index', { title: TITLE });
});

module.exports = router;

  

  注意:在public文件夹中创建avatar文件夹以供文件存放

运行结果

  1.在app.js中添加8000端口的监听

  2.cd到项目根目录,运行 node app

  3.浏览器上访问 localhost:8000

  

  4.上传图片

  
  5.去上传文件夹中查看

  

  大功告成!

部分疑惑解析

  有一些在代码中有注释的我就不解释了

  

  1.怎么没看到上传?

  注意:form.parse  再看看formidable的解释

Automatically writing file uploads to disk

  2.为什么需要fs.renameSync

  原因和上一个问题有关,它会自动被上传到用户的临时目录(这个可以把files.fulAvatar.path输出来看一下便知) http://nodejs.org/docs/latest/api/fs.html#fs_fs_renamesync_oldpath_newpath

  3.可不可以看到上传进度

  可以,https://github.com/felixge/node-formidable#events (仔细看看events,可能有你要用的其它部分)

  但是只是在控制台输出,想在前端去显示进度条是不行的(没有去研究,想想别的办法应该也可以)

  4.文件名想命名UUID不重复,在nodejs中怎么办?

  可以使用node-uuid,调用简单  https://github.com/broofa/node-uuid

  ...

  其它的留言问吧^_^!

写在之后

  功能比较简单,代码也是示例风格,大家主要关注一下使用

  代码结构优化方向:

  1.比如文件后缀这一类的方法可以放到一个pub.js中,此js专门用于这些公有方法

  2.可以利于返回值的方式去返回数据,前端根据返回值做出相应的提示

  3.可以利于jquery.form.js去提交表单,post中用res.json方法返回值,优化体验(同样引用这个js也会增大页面体积)

  ....

  总之是个小例子,大家将就着看看吧^_^!

Nodejs学习笔记(八)--- Node.js + Express 实现上传文件功能(felixge/node-formidable)的更多相关文章

  1. Web 在线文件管理器学习笔记与总结(19)上传文件

    dir.func.php 中添加方法: /* 上传文件 */ function uploadFile($fileInfo,$path,$allowExt = array('jpg','jpeg','p ...

  2. Nodejs学习笔记(五)--- Express安装入门与模版引擎ejs

    目录 前言 Express简介和安装 运行第一个基于express框架的Web 模版引擎 ejs express项目结构 express项目分析 app.set(name,value) app.use ...

  3. nodejs学习笔记二:解析express框架项目文件

    上一章介绍了如何去创建一个express框架的工程项目,这章介绍一下express框架下的文件和用法解析,上一张我们创建的工程项目结构图如下: models是不属于原工程项目结构,为了实现数据模型后添 ...

  4. nodejs学习笔记一:安装express框架并构建工程目录

    偶遇node是在一个阳光明媚的上午,无意间打开博客看到一片关于nodejs的介绍,通读全篇后,心情跌宕起伏,哎呀,这么好的东西我竟然现在才知道,这是最气的,于是马上开始制定学习nodejs计划,好了, ...

  5. [javascript] ajaxfileupload.js 跨域上传文件

    原文地址: http://www.ueffort.com/jqueryajaxfileupload-js-duo-wen-jian-shang-chuan-chuan-zhi-kua-yu/ 跨域 这 ...

  6. 使用ajaxfileupload.js实现上传文件功能

    <div class="pictureList"> <div class="pictureItem" id="uploadItem& ...

  7. Node使用multiparty包上传文件

    var multiparty = require('multiparty'); var http = require('http'); var util = require('util'); var ...

  8. js无刷新上传文件

    传统的文件上传方式 <form action="" method="POST" enctype="multipart/form-data&quo ...

  9. Nodejs学习笔记(六)--- Node.js + Express 构建网站预备知识

    目录 前言 新建express项目并自定义路由规则 如何提取页面中的公共部分? 如何提交表单并接收参数? GET 方式 POST 方式 如何字符串加密? 如何使用session? 如何使用cookie ...

随机推荐

  1. 前端开发面试题收集(css部分)

    http://davidshariff.com/quiz/ 做了下这里面前端开发面试的题,发现有些不会,所以在此做个整理以供自己学习,参考,总结. 1.问: CSS属性是否区分大小写? ul { Ma ...

  2. SQL Server 2016正式版安装(超多图)

    微软数据库SQL Server 2016正式版在2016年6月就发布,由于近期工作忙,一直拖到现在才有时间把安装过程写到博客上,分享给大家.本人一直习惯使用英文版,所以版本和截图都是英文版的.废话少说 ...

  3. 浅谈WEB跨域的实现(前端向)

    同源策略/SOP(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS.CSFR等攻击(可以参考我的这篇文章). SOP要求 ...

  4. JSON字符串与JSON对象的区别

    Q:什么是"JSON字符串",什么是"JSON对象",两者的区别? a.JSON对象是直接可以使用JQuery操作的格式,如C#中可以用对象(类名)点出属性(方 ...

  5. shape 代码生成器

    场景: 可以尝试使用shape的xml文件来代替图片. 可以起到减小包大小的效果. Android Button Maker是一个可以在线生成按钮代码的工具.Android API提供了XML文件定义 ...

  6. NAT技术

    该文摘自百度百科"NAT"中的一部分 NAT(Network Address Translation,网络地址转换)是1994年提出的.当在专用网内部的一些主机本来已经分配到了本地 ...

  7. mysql字段类型

    会安装mysql,会几条sql语句,会jdbc,会hibernate配置,以为就会mysql了,最近几天面试被问到mysql的问题,无地自容,系统的学习一下. mysql优化之一,选择合适的而不是最大 ...

  8. 架设 OpenLDAP服务器

    OpenLDAP是一个开放源代码的软件,可以免费获取使用,其主页地址是:http://www.openldap.org/.在RHEL 6上安装OpenLDAP还需要libtool-ltdl-2.2.6 ...

  9. css属性选择器

    1.E[att] 选择具有attr属性的E元素.2.E[att="val"] 选择具有att属性且属性值等于val的E元素3.E[att~="val"] 选择具 ...

  10. Excel 二级下拉菜单

    http://jingyan.baidu.com/article/cd4c2979f31967756f6e6066.html http://hi.baidu.com/chenshake/item/e1 ...