formidable+express+element-ui处理单张/多张图片上传

一张图片前端代码:

<el-upload
            class="upload-demo"
            action="http://localhost:3000/upload" //后端api地址
            :data="uploadData" //要附带的数据,这里带了用户名传到后端
            :on-success="getAvatarSuccess"  //成功之后的回调函数,第一个参数
            //是后端返回的值
            :before-upload="beforeAvatarUpload"//上传之前的预处理函数
            list-type="picture"//缩略图
            >
<el-button size="small" type="primary">点击上传头像</el-button>

script部分:

data(){
 return{ 
         avatar:'',
         uploadData:{
              name:""
          },
      }
    }
},
 methods:{
    beforeAvatarUpload(file){
          const isLt=file.size/1024/1024/<4;
          const isJPG=file.type=='image/jepg';
          if (!isJPG) {
            this.$message.error('上传头像图片只能是 JPG 格式!')
          }
          if (!isLt) {
            this.$message.error('上传头像图片大小不能超过 4MB!')
          }
          return isLt&&usJPG;//以此让组件判断是否发起请求
     }
     getAvatarSuccess(res){
       this.avatar=res.avatar
       //注意,若想给img动态绑定src,必须用require($baseIMGurl+this.avatar);
   }
}

后端部分:

要用到formidable中间件,即cnpm install formidable;
原理分析:
form.parse会解析从前端传来的req里的表单数据,把username等放在fields中,把图片文件等放在files中,可以自己打印一下看看,主要过程是得到图片->修改名字->保存->发送图片新名字到前端(是新名字,不包括基本路径,基本路径在前端设置好,这样利于在数据库保存图片的路径)

app.post('/upload', (req, res) => {
  let form = new formidable.IncomingForm()
  form.encoding = 'utf-8' // 编码
  form.keepExtensions = true // 保留扩展名
  form.uploadDir ='src/assets/images/' //文件存储路径 最后要注意加 '/' 否则会被存在public下
  ;
  form.parse(req, (err, fileds ,files) => { // 解析 formData 数据
    if(err) return next(err) 
    let username = fileds.name //用户名 用于修改用户头像路径
    let oldPath = files.file.path //获取文件路径 ~/public/images/<随机生成的文件名>.<扩展名>
    let imgname = files.file.name //前台上传时的文件名 也就是文件原本的名字
    let userImgname = imgname.replace(/[^.]+/, username) //把扩展名前的文件名给替换掉
    //我这里为了方便存储 统一将文件名改为 <用户名>.jpg
    let newPath = path.join(path.dirname(oldPath), userImgname) ;
    fs.rename(oldPath, newPath, (err) => {//fs重命名
      if(err) return next(err)
      res.json({ avatar: userImgname }) ;
      })
  })
})

下面是多张图片教程:

前端代码:

原理分析:先取消upload组件自动上传,指定http-request(上传规则)函数
,利用FormData对象的append属性,往formdata中添加图片数据,传到后端;
在按下确定按钮后,this.$refs.upload.submit()触发,这之后的append才会生效
接着往formdata中append图片数据即可

<el-upload
          class="upload-demo"
           multiple
           action="http://localhost:3000/uploads" 
           list-type="picture-card"
           :auto-upload="false"
            :http-request="uploadFile"
             ref="upload"
              >
             <i class="el-icon-plus"></i>
         <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且单个不超过4M</div>
      </el-upload> 
       <span slot="footer" class="dialog-footer">
         <el-button @click=" dnc_cancle">取 消</el-button>
         <el-button type="primary" @click="dnc_confirm">确 定</el-button>
        </span>

前端script部分:

uploadFile(file){
                 this.imgsArr.push(file.file);//往一个数组中添加图片数据
            },
dnc_confirm方法:
          this.$refs.upload.submit();
            var index=1;//用来给图片命名
            this.textarea='';
       
              this.imgsArr.forEach((img,index)=>{
              this.formDate.append(`img${index++}`,img);//这里用到index++,防止前面添加的图片被后面的覆盖,下面后端代码有讲如何循环这个数组
            })
            this.formDate.append('username',this.uploadData.name);
            this.formDate.append('info',this.info);
            let config = {
                headers: {
                'Content-Type': 'multipart/form-data'
                }
            }//设置请求头!
            this.$axios.post('http://localhost:3000/uploads',this.formDate,config).then(inf=>{
                this.info="";
                this.$message.success('添加成功');
                this.dialogVisible=false;
                this.reload();
            })

后端代码:

 const form=new formidable.IncomingForm();
  form.uploadDir='src/assets/d-image/';
  form.keepExtensions=true;
  form.encoding='utf-8';
  const imgArr=[];
   form.parse(req,(err,fields,files)=>{
       if(err)console.log(err);
        for(var key in files){//循环files对象
          const file=files[key];
          const oldPath=file.path;
          const oldName=file.name;
          const newName=oldName.replace(/[^.]+/,Math.random()+parseInt(new Date().getTime()));//以时间戳命名+random,防止图片重名
          const newPath=path.join(path.dirname(oldPath),newName);
          fs.rename(oldPath,newPath,(err)=>{
           if(err) return next(err);
          imgArr.push(newName);//把图片新名字压进数组
          });       
      res.json({state:1,imgs:imgArr});

发布了6 篇原创文章 · 获赞 0 · 访问量 45

猜你喜欢

转载自blog.csdn.net/zisuu/article/details/104281706