小程序图片上传formdata boundary + base64


1、使用 boundary


因为小程序上传图片只能单图上产,想着上传图片的时候直接for循环搞上去,谁知后台要一个文件类型(boundary),就这样头疼的搞了一中午,直接先看效果吧
![在这里插入图片描述](https://img-blog.csdnimg.cn/2021070516200750.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzA5MDAxOA==,size_16,color在这里插入图片描述
在这里插入图片描述

小程序只提供了wx.requestwx.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 = this
    const fs = wx.getFileSystemManager()
    const {
      type
    } = e.currentTarget.dataset
    let fp = app.globalData.uploadImgs
    let 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.data
        that.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 = true
    let 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.dataset
    let res = await Util.uploadImages(1, type)
    for (let i = 0; i < res.length; i++) {
      let tType = res[i].type
      this.setData({
        [tType]: {
          imgUrl: res[i].imgUrl,
          imgBoundary: res[i].imgBoundary
        }
      })
    }

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值