• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

超级飞燕

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

Vue+express 实现文件上传

文件上传 前端 FormData 上传文件 只有 FormData 数据格式,可以直接上传文件 后端接收 FormData 数据 安装 multiparty 模块 获取FormData数据,响应客户端

文件上传

前端 FormData 上传文件

只有 FormData 数据格式,可以直接上传文件

let formData = new FormData() // 实例化一个FormData对象
formData.append('file', file) // 将文件加入FormData对象中
formData.append('username', username) // 将普通数据加入FormData对象中
axios
  .post('/upload', formData) // axios发起post请求,携带FormData参数
  .then((response) => {
    console.log(response)
  })
  .catch((error) => {
    console.log(error)
  })

后端接收 FormData 数据

安装 multiparty 模块

npm i multiparty

获取 FormData 数据,响应客户端

app.post('/upload', (req, res) => {
  let form = new multiparty.Form(); // multiparty实例化form
  form.uploadDir = './upload';      //  配置文件存储路径
  form.parse(req,function(err, fields, files) { // 解析FormData
    console.log(files.file[0])      // files 中存储的是文件
    console.log(fields.username[0]) // fields 存储的是普通数据
    // ......操作数据
    res.json({    // 响应客户端
      code:200,
      msg:'上传成功'
    })
  }
})

实战演练

前端

捕获.PNG

<el-dialog title="提示" :visible.sync="showBox" width="30%">
  <!-- 选择图片 -->
  <div class="uploadAvatorBox">
    <div class="selectBox">
      <label for="file">
        <div class="inputBox">选择图片</div>
      </label>
      <input
        type="file"
        name="file"
        id="file"
        @change="uploadAvator"
        accept="image/*"
        capture="camera"
        style="display: none"
      />
    </div>
    <!-- 预览图片 -->
    <div class="img" v-if="showUploadImg !== ''">
      <img
        :src="showUploadImg"
        alt=""
        style="width: 200px; height: 200px; margin: 10px auto"
      />
    </div>
  </div>
  <span slot="footer" class="dialog-footer">
    <el-button @click="showBox = false">取 消</el-button>
    <!-- 上传图片 -->
    <el-button type="primary" @click="uploadImg">上传</el-button>
  </span>
</el-dialog>

FormData上传文件
捕获1.PNG

    // 点击头像,显示修改头像弹框
    handleShowBox() {
      console.log("显示弹框 上传 修改 下载头像");
      this.showUploadImg = "";
      this.showBox = true;
    },

    // 点击选择头像按钮
    uploadAvator(e) {
      if (this.avator !== "") {
        this.type = "updata";// 更新头像
      } else {
        this.type = "add";// 首次上传头像
      }
      let file = e.target.files[0]; // 从input获取文件

      // 以文件形式上传
      this.formData = new FormData(); // 实例化一个FormData对象
      this.formData.append("avatar", file); // 将文件加入FormData对象中
      this.formData.append("username", this.userInfo.username);
      this.formData.append("id", this.userInfo._id);
      this.formData.append("type", this.type);

      // 文件转base64,预览图片
      let reader = new FileReader(); // 实例化文件读取对象
      reader.readAsDataURL(file); // 将文件读取为base64格式
      reader.onload = () => { // 读取完成时的回调
        this.showUploadImg = reader.result; // reader.result=e.target.result存储的是文件的base64编码
        const base64Str = reader.result;
        console.log(base64Str); //data:image/webp;base64,UklGRuYxAABXRUJQVlA4IN
      };
    },

    // 点击确定按钮,上传头像
    uploadImg() {
      console.log("上传头像");
      this.$axios.post("/userAvatar", this.formData).then((res) => {
        if (res.data.code === 200) {
          console.log(res.data.imgPath);
          this.showBox = false;
          this.avator = "http://127.0.0.1/" + res.data.imgPath; // 头像上传成功,从服务器获取静态资源
        }
      });
    },

后端

Snipaste_2022-03-25_09-46-53.png
express 接收 FormData 数据,存储图片到静态托管目录

exports.userAvatar = (req, res) => {
  console.log('头像上传')
  let form = new multiparty.Form()
  form.uploadDir = './public/img'
  form.parse(req, function (err, fields, files) {
    // 解析FormData
    const file = files.avatar[0]
    const username = fields.username[0]
    const id = fields.id[0]
    const type = fields.type[0]
    const oldP = file.path // 就文件名
    const suffix = oldP.split('.')[1] //文件扩展名
    const date = new Date().getTime() //当前时间戳
    const newP = 'public/img/' + username + '-' + date + '.' + suffix // 组装新文件名
    console.log(oldP, newP)
    fs.rename(oldP, newP, async (err) => {
      // 文件重命名
      if (err) {
        throw err
      } else {
        // 将用户头像服务器地址 存储在用户信息的avatar上
        const result1 = await User.find({ username: username }) //查询用户信息
        const oldImg = result1[0].avatar
        const avatarP = {
          avatar: newP,
        }
        const user1 = Object.assign(result1[0], avatarP)
        console.log(user1)
        const result = await User.updateOne(
          //更新用户信息
          { _id: id },
          user1,
        )
        if (result.matchedCount === 1) {
          console.log('更新成功')
          res.json({
            code: 200,
            msg: '头像上传成功',
            imgPath: newP,
          })
          // 如果是更新头像,删除旧头像
          if (type === 'updata') {
            console.log(oldImg)
            fs.unlink(oldImg, function () {
              console.log('删除成功')
            })
          }
        }
      }
    })
  })
}

posted on 2022-03-25 09:13  超级飞燕  阅读(604)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3