1、使用 boundary
因为小程序上传图片只能单图上产,想着上传图片的时候直接for循环搞上去,谁知后台要一个文件类型(boundary),就这样头疼的搞了一中午,直接先看效果吧
![在这里插入图片描述](https://img-/07051650.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzA5MDAxOA==,size_16,color
小程序只提供了wx.request
和wx.uploadFile
这两种post请求,在我想。request中只需要将data变为ArrayBuffer类型就可以了
multipart/form-data的数据格式是这个样子的
数据body被Boundary分隔成几部分,Boundary的值为content-type里的boundary。
每部分包含Content-Disposition,name,filename,换行符\r\n,Content-Type和内容
最后以’–’+Boundary+’–'结尾
1、生成随机分隔符
//生成分割字符串generateDivisionStr() {return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {let r = Math.random() * 16 | 0,v = c == 'x' ? r : (r & 0x3 | 0x8)return v.toString(16);})},
2、封装上传所需参数
generateUploadParams(str,obj) {let pra = ''Object.keys(obj).forEach(key => {//如果是ArrayBuffer类型的图片文件if(typeof obj[key] === "object"){//随机图片文件名let iName = this.generateDivisionStr()pra += `\r\n--${str}` +`\r\nContent-Disposition: form-data; name="${key}";filename="${iName}.png"` +`\r\nContent-Type: "image/png"`+`\r\n` +`\r\n${obj[key]}` }else{pra += `\r\n--${str}` +`\r\nContent-Disposition: form-data; name="${key}"` +`\r\n` +`\r\n${obj[key]}` }})pra = pra + `\r\n--${str}--`console.log(pra)return pra},
3、使用方法
1、当选择图片的时候
bn:就是处理后的图片
//上传图片async handleUploadImg(e) {let that = thisconst fs = wx.getFileSystemManager()const {type} = e.currentTarget.datasetlet fp = app.globalData.uploadImgslet res = await Util.uploadImages(1, type)this.setData({[type]: res.join('').replace(/\s*/g, "")})console.log(fp)fs.readFile({filePath: fp[0].file[0], //要读取的文件的路径 如果不传 encoding,则以 ArrayBuffer 格式读取文件的二进制内容success(res) {console.log(res.data)that.bn = res.datathat.setData({bn: res.data})}})},
2、点击提交的时候提交输入的数据和图片
onClickVerify() {const obj = {"ownerInfo.name": 111,"ownerInfo.identityNo": 222,"imgs[0].file": this.bn,"imgs[0].type": 1}//这里的分隔符一定要是同一个let str = this.generateDivisionStr()let data = this.generateUploadParams(str,obj)Util.request({url: "http://192.168.18.43:18930/ebikeOrderInfo/uploadData",method: 'POST',header: {'content-type': `multipart/form-data; boundary=${str}`},data,success: function (res) {},})}
2、使用base64
多图上传的时候我们也可以将图片转为base64给后台,让后台再将base64转换为图片,这样就不用微信的限制,一次只能传一个
utils.js(其他封装的就不写了)
class Util {type为图片类型,因为项目中要对不同的图片进行标识,并传给后台static uploadImages(count, type) {let app = getApp()let flag = truelet maxSize = 1024 * 1024// 1:编码 2:后方45° 3:证反面 4:证正面 5:车牌6:拓印const imgType = {'carCodeImg': 1,'carAngleImg': 2,'cardPositiveImg': 3,'cardSideImg': 4,'carImages': 5,'rubbingImg': 6}return new Promise((resolve, reject) => {wx.chooseImage({count: count || 1,success:(res) => {for (let i = 0; i < res.tempFiles.length; i++) {const fs = wx.getFileSystemManager()fs.readFile({encoding: "base64",filePath: res.tempFiles[i].path,success(val) {wx.getImageInfo({src: res.tempFiles[i].path,success(info) {// resolve(res.tempFilePaths)app.globalData.uploadImgs.push({file: res.tempFilePaths,type: imgType[type],imgTypes: info.type,type,imgUrl: res.tempFilePaths.join('').replace(/\s*/g, ""),imgBoundary: `data:image/${info.type};base64,${val.data}`})resolve(app.globalData.uploadImgs)}})}})}},fail(err) {reject(err)}})})}}module.exports = Util
在需要用到的页面引入后
async handleUploadImg(e) {const {type } = e.currentTarget.datasetlet res = await Util.uploadImages(1, type)for (let i = 0; i < res.length; i++) {let tType = res[i].typethis.setData({[tType]: {imgUrl: res[i].imgUrl,imgBoundary: res[i].imgBoundary}})}