小程序使用formdata上传图片

目标

实现小程序端单张图片上传。前端通过formdata将文件数据传递到后端。后端用MultipartFile类型接收文件数据。

遇到的困难:
微信本身没有FormData对象,无法使用 new FormData。经过搜索找到解决办法。微信开放社区 | github(个人认为微信开发者社区中的解决办法更适合键值对的传递,而传文件的话还是用github大神自己写的FormData.js)

环境

后端 
javaSpring
前端:
小程序 wxml wxss js @vant-ui

后端接口

    @PostMapping("/upload")
    public ResponseVO<String> upload(@RequestBody MultipartFile file, @RequestParam FileType fileType) {
        return new ResponseVO<>(fileService.upload(file, fileType));
    }

前端代码

展示项目的背景是头像展示和更改。

图片上传组件

使用的是@vant 的 van-uploader 可以按需引入。

.wxml
```html
<van-uploader file-list="{{ fileList }}" accept="image" bind:after-read="changeAvatar" bind:delete="deleteAvatar" deletable="{{ true }}" max-count="1">
   <view>
    <image class="avatar" wx:if="{{portrait}}" src="{{portrait}}" />
    <image class="avatar" wx:else="{{portrait}}" src="path/images/user-unlogin.png" />
   </view>
</van-uploader>
  <!-- 
  file-list 用于图片预览,并不是双向绑定的,需要手动的添加删除
  bind:after-read 图片上传后触发
  bind:delete 图片删除后触发
  slot的地方可以自定义样式,这里我用来展示用户目前的头像
 -->

.js

/**
	上传图片前处理数据
*/
 changeAvatar(e) {
  const file = e.detail.file;
   console.log(file);
   //{size: 856983, type: "image", url: "http://tmp/8OH83lYy8YoH355bbf08b9248c35fc20d92f0c5d6c88.png", thumb: "http://tmp/8OH83lYy8YoH355bbf08b9248c35fc20d92f0c5d6c88.png"}
  //图片上传组件并没有获取图片的名字,这里截取一部分做图片命名。如果后端不会重命名的话,可以采取加上时间戳的方式避免名字重复
  let _name = file.url.split("\/");
  let name = _name[_name.length-1];
  name = name.length > 10 ? name.substring(name.length - 9, name.length) : name;
  this.setData({
   imgFile: file.url,
   fileName: name
  });
  this.setData({
   fileList: [file]
  });/这里是
  that.updataAvatar();//向后端传数据
 },
 deleteAvatar(e) {
  this.setData({
   imgFile: "",
   fileList: []
  });
 },

效果
在这里插入图片描述

formdata传递

首先下载 https://github.com/zlyboy/wx-formdata 的代码,然后放在util文件夹下。

仓库中的README有使用方法。需要注意以下两点:

  1. 引入:const FormData = require('../../utils/formdata/formData')
  2. append类型:append()方法来添加字段调用appendFile()方法添加文件
    .js
 /**
  * 上传头像
  */
 uploadAvatar() {
  let that = this;
  let upload = new FormData();
  upload.appendFile(
   "file", that.data.imgFile, that.data.fileName
  );
  let data = upload.getData();
  console.log(data.buffer);

  wx.request({
   url: 'http://localhost:9720/file/upload?fileType=PORTRAIT',
   method: 'POST',
   header: {
    'content-type': data.contentType,
    token: that.data.account.token
   },
   data: data.buffer,
   success: function (res) {
   	 //上传成功
     that.setData({
      portrait: res.data.data
     });
     wx.showModal({
      title: '信息',
      content: res.data.message,
      confirmText: '确认'
     }); //showModal
   }//success
  });
 },

成功发送formdata的数据时的请求是这样的
在这里插入图片描述
在这里插入图片描述

web网页

如果是web端的话使用formdata就简单多了,记录一下。

//element-ui
<el-upload
    class="avatar-uploader"
    action=""
    :auto-upload="false"
    accept=".jpg,.jpeg,.png,.JPG,.JPEG"
    :show-file-list="false"
    :on-change="getImageLocalUrl"
    :before-upload="beforeAvatarUpload"
     >
     <img
        v-if="userInfo.portrait"
        :src="userInfo.portrait"
         class="avatar"
     />
     <i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
//script
getImageLocalUrl(file, fileList) {
	this.userInfo.portrait = URL.createObjectURL(file.raw);
	this.imgFile = file.raw;	
    this.uploadAvatar();
},
uploadAvatar(){
	let upload = new FormData();
    upload.append("file", this.imgFile);
    this.$axios
    	.post("/file/upload?fileType=PORTRAIT", upload)
        .then(async (res) => {
        	_this.$message.success({
            	message: "更新成功!",
                duration: 1500,
                showClose: true,
            });
        }).catch((err) => err);
}

总结

  1. 为什么要用formdata呢?因为需要传递给后端的数据,除了文件本身的二进制码还有文件的格式,命名等其他信息。并且用json传递的话可能会涉及到转码的问题。具体可见参考
  2. 关于formdata更加深入的理解可见参考
  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于多张图片的上传,可以使用form表单的方式,并设置input的multiple属性。具体代码如下所示: ```html <form action="http://192.168.171.144/api/xxx" method="post" enctype="multipart/form-data"> 内容content: <input name="content" type="text" /> 图片images: <input name="images" multiple="multiple" type="file" /> <input type="submit" value="提交" /> </form> ``` 通过以上代码,可以实现多张图片的上传功能。 另外,如果你使用的是微信小程序开发,则需要注意微信本身没有FormData对象,无法直接使用new FormData。但可以通过wx.request发送multipart/form-data请求来模拟FormData的效果。具体代码如下所示: ```javascript wx.request({ url: app.globalData.pubUrl + '/Upload/UploadFile', // 接口地址 method: 'post', header: { 'content-type': 'multipart/form-data; boundary=XXX', 'Authorization': app.globalData.token }, data: '\r\n--XXX' + '\r\nContent-Disposition: form-data; name="UploadId"' + '\r\n' + '\r\n' + UploadId + '\r\n--XXX' + '\r\nContent-Disposition: form-data; name="IsDelete"' + '\r\n' + '\r\n' + IsDelete + '\r\n--XXX--', success: function (res) { // 接口成功返回的处理逻辑 if (res.data.success == false) { wx.showToast({ title: res.data.msg, icon: 'none', duration: 2000 }) } } }) ``` 以上代码中,需要自行替换URL、请求参数和请求头部信息,其中UploadId和IsDelete为上传图片接口所需的参数值。 请注意,以上代码是针对微信小程序开发中的图片上传情况,如果你使用的是其他平台或开发框架,请参考对应文档进行处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [通过JS创建FormData实现上传多张图片](https://blog.csdn.net/weixin_43974265/article/details/122016416)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [小程序FormData格式传参(上传图片,删除图片)](https://blog.csdn.net/weixin_45683261/article/details/128305221)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值