vue+node实现头像上传功能

实现思路

前端处理(vue):

1.点击头像,打开文件处理系统(PC端的文件系统,移动端的相册)
2.选择头像图片,点击确认,读取图片数据进行处理成统一规格的图片资源,通过post请求将图片发送到后端
3.获取后端传递的数据,更改图片img的src属性

后端处理(node):

1.读取post请求中的图片数据
2.用hash函数生成图片名称(生成唯一图片名称)
3.将图片保存到public/userIcon目录下
4.将图片路径即(public/userIcon/图片名称)保存到数据库中
5.将图片路径返回到前端

前端处理

1.点击头像,打开文件处理系统(PC端的文件系统,移动端的相册)
建立一个input file 文件 打开文件系统(如果有更好的方法请写在评论中~~)
增加事件监听器获取选中文件信息
对文件进行读取
Tip:文件读取会遇到this指针问题,箭头函数不适用于该情况,创建一个变量保存外层的this

 try {
        if (this.inputObj == null) {
          //建立一个input file 文件 打开文件系统()
          this.inputObj = document.createElement("input");
          this.inputObj.setAttribute("id", "_ef");
          this.inputObj.setAttribute("type", "file");
          this.inputObj.setAttribute("style", "visibility:hidden");
          document.body.appendChild(this.inputObj);
          //增加事件监听器获取选中文件信息
          document.querySelector("#_ef").addEventListener("change", e => {
            for (let entry of e.target.files) {
              var resultFile = e.target.files[0];
              console.log(resultFile);
              if (resultFile) {
              //读取文件信息
                var reader = new FileReader();
                reader.readAsDataURL(resultFile);
                var that = this;
                reader.onload = function(e) {
                  //读取数据后将数据上传到后台
                  var urlData = this.result;
                  ************************
                          第二步
                  ************************
        
                };
              }
            }
          });
          this.inputObj.click();
          console.log(this.inputObj);
        } else {
          this.inputObj.click();
        }
      } catch (e) {
        Toast("请确定是否存在该盘符或文件");
      }

2.选择头像图片,点击确认,读取图片数据进行处理成统一规格的图片资源,通过post请求将图片发送到后端

 //发送请求
  console.log(urlData)
    let param = new URLSearchParams();
    param.append(
      "userName",
      that.$cookieStore.getCookie("userInfo")
    );
    param.append("pic_data", urlData);
    axios({
      method: "post",
      url: "http://localhost:3000/userPicChange",
      data: param
    })
      .then(res => {
        var data = res;
        if (data && data.status == 200) {
          //200: '服务器成功返回请求的数据,更改图片资源
         ***********************************
         		 		第三步         
		 ***********************************
        }
      })
      .catch(function(err) {
        console.log(err);
      });

3.获取后端传递的数据,更改图片img的src属性

that.$store.state.user_Info.client_pic="http://localhost:3000/"+data.data.path
that.inputObj.parentNode.removeChild(that.inputObj);
that.inputObj=null

后端处理(node):

1.读取post请求中的图片数据

// 处理图片
var imgData = req.body.pic_data;
//过滤data:URL
var base64Data = imgData.replace(/^data:image\/\w+;base64,/, "");
var dataBuffer = new Buffer.from(base64Data, 'base64'); // 解码图片

2.用hash函数生成图片名称(生成唯一图片名称)
后来用账户+时间的形式生成唯一值,这样的做法可以查看账户的历史头像

 //生成图片名称
//用户账户*时间
var d = new Date();
var img_name = req.body.userName + d.getTime();
var img_path = "public/userIcon/"+ img_name + ".png"
console.log(img_name)

3.将图片保存到public/userIcon目录下

fs.writeFile(img_path, dataBuffer, function (err) {
        if (err) {
            res.send("图片保存失败" + err);
        } else {
            //调用数据库方法存储图片
            DB.userPicChange(img_path,req.body, function (err, data) {
                if (err) {
                    res.status = 500
                    res.send('数据库查询错误,请联系数据库操作人员')
                } else {
                    res.header("Access-Control-Allow-Origin", "*");
                    res.status = 200
                    var JsonData={
                        path:img_path
                    }
                    res.json(JsonData)
                }
            })
        }
    });

4.将图片路径即(public/userIcon/图片名称)保存到数据库中

exports.userPicChange = function (pic_path,user_data, callback) {
    //1.连接数据库
    connection = connect();
    //2.设置查询语句
    commit = "CALL client_changeIcon('" + pic_path + "','" + user_data.userName + "');"
    console.log(commit)
    connection.query(commit, function (error, results, fields) {

        if (error) {
            callback(error, null)
        } else {
            if (results.affectedRows >= 1) {
                callback(null, results)
            }
        }
    });
    connection.end();
}

效果演示

你可能感兴趣的:(web,vue,js,node)