赞
踩
实现小程序端单张图片上传。前端通过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: [] }); },
效果
首先下载 https://github.com/zlyboy/wx-formdata 的代码,然后放在util文件夹下。
仓库中的README有使用方法。需要注意以下两点:
const FormData = require('../../utils/formdata/formData')
append()
方法来添加字段调用appendFile()
方法添加文件。/** * 上传头像 */ 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端的话使用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); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。