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

  • 相关阅读:
    Map集合
    Collections 工具类
    LinkedList 集合
    List集合
    Iterator迭代器
    Collection集合
    时间日期类
    一看就懂!速写docker 容器数据库备份脚本
    Nginx 配置之HTTPS和WSS那些你不知道的事!
    https 证书认证/颁发/秒级认证无烦恼
  • 原文地址:https://www.cnblogs.com/alice626/p/5176004.html
Copyright © 2011-2022 走看看