vue+element+node 实现图片上传功能

本文介绍了使用ElementUI组件库实现图片上传功能,包括选择图片、文件格式校验以及使用formData进行数据封装。在后端,通过formidable解析上传的formData,并存储到本地及数据库。关键点包括before-upload钩子用于文件格式验证,以及formData.append()方法添加上传文件。
摘要由CSDN通过智能技术生成

1.前端部分

  1.  使用element组件库制作上传的按钮。上传的流程分为两步:选择图片—>图片上传。
<el-button style="margin-left: 10px;" type="danger" size="small"  @click="pictureUploads()">图片上传</el-button>
    <el-upload
      class="uploadZZ"
      action
      :auto-upload="false"
      :show-file-list="false"
      accept=".png,.pdf"
      :before-upload="beforeUpload"
      :on-change= onchange
    >
    <el-button style="margin-left: 10px;" size="small" type="primary">选择图片</el-button>
    </el-upload>

根据element官方文档所知,auto-upload默认true,选择文件之后会自动上传;before-upload为上传文件之前的钩子,参数为上传的文件,若返回 false 或者返回 Promise 且被 reject,则停止上传;show-file-list默认true,是否显示已上传文件列表;accept是支持上传的类型。

data:{
fileList:
}  

methods:{
          onchange(file, fileList) {
                this.fileList = [];
                this.fileList = fileList
                console.log(this.fileList)
            },

            beforeUpload(file) {

                let fileName = file.name.substring(file.name.lastIndexOf('.') + 1)
                const extension = fileName === 'png'
                const extension2 = fileName === 'pdf'
                if (!extension && !extension2) {
                    this.$message({
                        message: '上传文件只能是 png、 pdf格式!',
                        type: 'warning'
                    });

                    return false;
                }
                this.fileList.push(file)

            },
            pictureUploads(){
                if (this.fileList == undefined) {
                    this.$message.error("选择图片之后再上传!!")
                    return;
                }
                console.log("图片信息",this.fileList[0].raw)
                //将单位名称存放在fileList.raw中
                    
                var pictureReq = new FormData()

                pictureReq.append("file", this.fileList[0].raw)
            
                **Api.pictureUpload(pictureReq).then((res)=>{
                    console.log(res)
                    if (res.code == 200) {
                        //打印formData里的kv
                        for (var key of pictureReq.entries()) {
                             console.log(key[0] + ', ' + key[1]);
                            }   
                        alert("资质上传成功!")
                    } else {
                        this.$message.error("上传失败!")
                        }
                        }).catch(err =>{
                            this.$message.error("超时")
                            console.log("----",err);
                            this.fileList = []
                        })
                                    
            }  
}

beforeUpload的作用是在选择图片时对图片进行校验保证图片是png或者pdf的格式。

pictureUploads函数的作用是将封装好的数据与后端进行交互。

图片上传我使用formdata封装成二进制流传给后端,后端在进行解析。

   2.formData详解

 formData接口提供了一种表示表单数据的键值对 key/value 的构造方式。它将图片封装成二进制流进行传递。封装好的formData无法通过打印来查看到里面的具体内容,只能通过form DATa.get()来查看。

根据上面的实例,我们在选择图片之后,可以通过控制台看到图片的具体的信息:

 在进行封装的时根据自己得需要进行封装,因为我是单图片上传,所以我封装的是raw这一部分。

var pictureReq = new FormData()
pictureReq.append("file", this.fileList[0].raw)

formData.append()是进行添加数据的操作。虽然进行了添加数据的操作,但是如果在打印的时候直接打印formDATa,在控制台上仍然会显示“{}”。这并不代表着你数据没有添加进去,所以不需要疑惑。在想查看数据是否打印进去的话提供一下两种方法:

//方法一:
console.log(formData.get("file"))
//方法二:
 for (var key of pictureReq.entries()) {
      console.log(key[0] + ', ' + key[1]);
     } 

2.后端方法

 后端引用:formidable包进行表单的解析。

const formidable = require('formidable')
router.post('/pictureUpload', async(req, res, next)=> {
    //将图片存放到本地
    var uploadDir = path.join(global.projPath, "static", "data");
    const form = formidable({ multiples: false, uploadDir: uploadDir, keepExtensions: true })
    form.maxFieldsSize = 20 * 1024 * 1024; //上传文件的最大大小
    
    //解析 formData 数据
    form.parse(req, async(err, fields, files) => {
        if (files == undefined){
            res.send({
                code:500,
                data:"图片上传失败"
            })
            return;
        }else{
            let imgPath = files.file.path
            let imgName = files.file.newFilename
            let name= fields.name

            res.send({
                code : 200,
                data : { name:imgName,path:imgPath,name:name,}
            })
            //根据名称将图片地址存放到数据库中
            await table1Model.update({picture:files.file.filepath},{
                where:{
                    name: "123456"
                }
            })
        }
       return
   })
})

 form.parse(req,async(err, fields, files)=>{})进行表单(formData)的解析。其中files就是你前端封装的数据。可以进行打印查看前端封装的数据。假设你下面需要用到path,例子:var imgpath = files.file.path,,同时这个path同时也是你存放的地址。

fields:是文本域存放的地方

files:是文件存放的地方

我使用sequelize进行数据库连接。 所以必须使用异步。

如果在前端封装formData你封装了其他数据(非图片)例如:

formData.append("name","T02")

那么你后端在访问“name”的时候就需要通过fields进行访问,fields.name。

formData详解参考

formidable详解参考

遇见的问题:

formdate.get("file")打印出来有数据,但是在传到后端并解析之后为空检查一下几点:

1.是否在request.js中配置了headers,如有配置了一定要注释掉!!!!因为本身浏览器就会配置header,如果我们自己配置了之后会将浏览器的给覆盖掉。

2.检查api传递的值是否是formdata。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值