在nodejs中使用input file批量上传文件的方法

    最近做了一个菜谱类的网站,其中的菜谱上传是多表上传,有菜谱表、主料表、辅料表和步骤表,菜谱表和步骤表中都有图片的上传

   以步骤表为例,html代码如下:

<form id="form1">
        <div class="publicContent">
            <div class="addStep">
                <h3 class="stepTitle">步骤</h3>

            </div>
        </div>
        <div class="buttonPublic">
<input type="button" class="public" id="publicCook" value="发布">
</div>
</form>

步骤的步数是不确定的,在js文件中动态添加,js文件如下:

addStep();
    //动态添加步骤
    function addStep() {
        var  stepBox = $('<ul class="stepBox"></ul>');
        $('.addStep').append(stepBox);

        for(var i = 0 ; i < 3 ; i++){
            var n = i + 1;
            var stepLi = $('<li class="stepLi"></li>');
            stepLi.attr('data-id',n);

            var stepDiv = $('<div class="stepDiv"></div>');
            var stepImg = $('<img src="">');
            stepImg.prop('id','img'+n);
            stepDiv.append(stepImg);
            var stepBtn = $('<input type="file" class="stepBtn" style="display: none">');
            stepBtn.prop('name','stepFile'+n);
            stepBtn.prop('id','stepBtn'+n);

            var stepNum = $('<input type="text"  class="stepNum">');
            // stepNum.prop('name','stepNum'+n);
            stepNum.val(n);
            var stepText = $('<textarea class="stepText"></textarea>');
            // stepText.prop('name','stepText'+n);

            var imgDiv = $('<div class="imgDiv"></div>');
            imgDiv.attr('data-id',n);
            var upImg = $('<img src="/images/publicHtml/up.png" class="upImg">');
            var downImg = $('<img src="/images/publicHtml/down.png" class="downImg">');
            var deleteImg = $('<img src="/images/publicHtml/delete.png" class="deleteImg">');
            imgDiv.append(upImg,downImg,deleteImg);

            stepLi.append(stepDiv,stepBtn,stepNum,stepText,imgDiv);

            stepBox.append(stepLi);
        }

        var addMore = $('<div class="addMore"></div>');
        var addOne = $('<a class="addOneMore">增加一步</a>');
        addMore.append(addOne);

        $('.addStep').append(addMore);
    }

注:form表单里的控件都需要加入name属性

ajax请求:

$('#publicCook').click(function () {
//input file中获取数据的方法FormDate()
       var fd = new FormData($('#form1')[0]);

        var stepArr = [];
//循环获取步骤中的数据
        for(var i = 0 ; i < $('.stepNum').length ; i++){
            var step = $('.stepNum').eq(i);
            var stepObj = {
                'stepNum': step.val(),
                'stepText': step.next().val()
            };
            stepArr.push(stepObj);
        }

        fd.append('userId',(JSON.parse(sessionStorage.user)).user_id);
        fd.append('cookStep',JSON.stringify(stepArr));


        $.ajax({
            url:'/users/public',
            data:fd,
            type:'POST',
            async:false,
            cache:false,
            contentType:false,
            processData:false,
            success:function (data) {
                // console.log('success:'+JSON.stringify(data));
                if(data.affectedRows == '1'){
                    alert('发布菜谱成功');

                }
            },
            error:function (err) {
                console.log(err);
            }
        });
    });

ajax发送后要在路由接受数据,在DAO层获取数据库数据,并将数据返回,route:

router.post('/public',function (req,res) {
  var form = new formidable.IncomingForm();

  form.parse(req,function (error,fields,files) {
    //fields接收文字,files接收文件(视频,图片,压缩包等)
    // console.log('fields:',fields);
    // console.log('files:',files);

      form.uploadDir = PUBLIC_PATH + 'images/';//上传目录
      form.keepExtensions = true; //保留后缀
      form.maxFieldsSize = 2*1024; //文件大小

      var step = JSON.parse(fields.cookStep);
         
          for(var key in files) {
              var extName = '';  //后缀名
              
              //强行匹配
              var a = key.substring(8)-1;
              // console.log(a);
              var sp = step[a];

              var file = files[key];
              form.uploadDir = PUBLIC_PATH + "images/";     //设置上传目录
              form.keepExtensions = true;     //保留后缀
              form.maxFieldsSize = 2 * 1024;   //文件大小
              var filename = saveImage(file,form.uploadDir);

              publicDao.addStep(sp,filename,fields.userId,function (result) {
                  res.send(result);
              });
          }

  });

});

这里对上传的图片名称进行了处理,使图片随机生成一个新的名称,方法如下:

function saveImage(file,uploadDir) {
    switch (file.type) {  //此处in_file  为页面端 <input type=file name=in_file>
        case 'image/jpeg':
            extName = 'jpeg';
            break;
        case 'image/jpg':
            extName = 'jpg';
            break;
        case 'image/png':
            extName = 'png';
            break;
        case 'image/x-png':
            extName = 'png';
        case 'video/mp4':
            extName = 'mp4';
            break;
    }
    // console.log('extName:',extName);

    try{
        if(extName.length == 0){
            res.render('error', { message: '只支持png和jpg格式图片' });
            return;
        }else {
            var fileName = Math.random() + '.' + extName;
            var newPath = uploadDir + fileName;

            // console.log(newPath);
            // console.log("old" + file.path);

            //文件保存
            fs.renameSync(file.path, newPath);  //重命名

            return fileName;
        }
    }catch(error){
        console.log(error);
    }

}

DAO层文件如下:

var query = require('./connConfig.js');

var publics = {
       addStep:function (obj,file,id,callback) {
        var sql = 'INSERT INTO t_step VALUES(null,?,?,?,?)';
        query(sql,[obj.stepNum,file,obj.stepText,id],callback);
    } 

};

module.exports = publics;

在这里需要注意route层传入的参数的顺序必须和DAO层的参数顺序一致

原文地址:https://www.cnblogs.com/zjm-html5/p/6283696.html