zoukankan      html  css  js  c++  java
  • NodeJs实现图片上传

    关于formidable

    NodeJs实现图片上传,此处主要用了插件:formidable

    github上关于formidable的资料如下:

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

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

    创建项目安装formidable

    1,创建项目sampleUpload

    cd 工作目录
    express -e sampleUpload

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

    {
      "name": "sampleUpload",
      "version": "0.0.0",
      "private": true,
      "scripts": {
        "start": "node ./bin/www"
      },
      "dependencies": {
        "body-parser": "~1.13.2",
        "cookie-parser": "~1.3.5",
        "debug": "~2.2.0",
        "ejs": "~2.3.3",
        "express": "~4.13.1",
        "morgan": "~1.6.1",
        "serve-favicon": "~2.3.0",
        "formidable":"latest"
      }
    }

    3,安装依赖项

    cd sampleUpload && npm install

    安装成功,开始完成这个功能,文件目录如下图:

    样式主要使用了bootstrap 3.0.3  https://github.com/twbs/bootstrap/releases/tag/v3.0.3

      JQuery:   官方下载

    不在bootstrap包中的两个css文件代码如下:

    body {
      min-height: 2000px;
    }
    
    .navbar-static-top {
      margin-bottom: 19px;
    }
    
    navbar-static-top.css
    navbar-static-top.css
    body {
      padding-top: 40px;
      padding-bottom: 40px;
      background-color: #eee;
    }
    
    .form-signin {
      max-width: 330px;
      padding: 15px;
      margin: 0 auto;
    }
    .form-signin .form-signin-heading,
    .form-signin .checkbox {
      margin-bottom: 10px;
    }
    .form-signin .checkbox {
      font-weight: normal;
    }
    .form-signin .form-control {
      position: relative;
      font-size: 16px;
      height: auto;
      padding: 10px;
      -webkit-box-sizing: border-box;
         -moz-box-sizing: border-box;
              box-sizing: border-box;
    }
    .form-signin .form-control:focus {
      z-index: 2;
    }
    .form-signin input[type="text"] {
      margin-bottom: 10px;
      border-bottom-left-radius: 0;
      border-bottom-right-radius: 0;
    }
    .form-signin input[type="password"] {
      margin-bottom: 10px;
      border-top-left-radius: 0;
      border-top-right-radius: 0;
    }
    
    signin.css
    signin.css

    app.js文件中添加端口号8200(可以随便定,只要不和其他的程序冲突即可)

    app.listen(8200,function(err){
       console.log("server started");
    });

    app.js中修改模板引擎为.html文件

    app.set('view engine', 'html'); //设置模板文件的后缀名为.html
    //运行ejs模板
    app.engine(".html",require("ejs").__express);

    index.html文件中构建表单并实现前端验证

    <!DOCTYPE html>
    <html>
      <head>
        <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>
        <h1><%= title %></h1>
       <div id="container" class="container">
           <% if(locals.success){%>
                <div id="alt_success" 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>
      <script src="/javascripts/jquery-2.1.4.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();
                var 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();
            alert(extName);
                if(extName!=".png" && extName!=".jpg"){
                    $("#container").prepend(errorTip.format("只支持png和jpg格式图片"));
                    return false;
                }
                return true;
            });
        })
      </script>
    </html>
    index.html

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

    实现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 = '';  //后缀名
            console.log("files.fulAvatar.type="+files.fulAvatar.type);
            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;
    index.js

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

    运行结果:

    在项目中遇到的问题:

    由于在html中代码写成:

    <input id="fulAvatar" name="fulAvater" type="file" class="form-control" /><br/>

    而在index.js中部分代码如下:

        form.parse(req, function(err, fields, files) {
    
            if (err) {
              res.locals.error = err;
              res.render('index', { title: TITLE });
              return;        
            }  
           
            var extName = '';  //后缀名
            console.log("files.fulAvatar.type="+files.fulAvatar.type);
            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 }); 

    运行之后总是报以下异常:

    虽然报异常,但是上传图片确是成功的,界面显示上传成功。

    原因是因为:

    虽然form.parse方法中有异常,但是它是异步的,不妨碍以下代码的执行:

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

    上传成功是因为:

    只要调用了form.parse方法就可以上传成功。

    最终找到原因是因为html中上传控件的name值为:

    <input id="fulAvatar" name="fulAvater" type="file" class="form-control" /><br/>

    与index.js中的files.fulAuatar不一致导致的。

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

    把index.html中代码为以下即可:

    <input id="fulAvatar" name="fulAvatar" type="file" class="form-control" /><br/>

    具体参考:

    http://www.cnblogs.com/zhongweiv/p/nodejs_express_formidable.html#node_web_install

  • 相关阅读:
    According to TLD or attribute directive in tag file, attribute end does not accept any expressions
    Several ports (8080, 8009) required by Tomcat v6.0 Server at localhost are already in use.
    sql注入漏洞
    Servlet—简单的管理系统
    ServletContext与网站计数器
    VS2010+ICE3.5运行官方demo报错----std::bad_alloc
    java 使用相对路径读取文件
    shell编程 if 注意事项
    Ubuntu12.04下eclipse提示框黑色背景色的修改方法
    解决Ubuntu环境变量错误导致无法正常登录
  • 原文地址:https://www.cnblogs.com/alice626/p/5176004.html
Copyright © 2011-2022 走看看