Uniapp + vue3 + ts 微信小程序多文件上传

没头脑

作者 没头脑

创建时间 2023-04-23

更新时间 2023-04-25

阅读 150

评论 0

预备知识点

FormData: 将数据以键值对的方式,发送给HTTP请求
Uint8Array: 8位无符号整型数组(0-255),即字节数组
ArrayBuffer:对象用来表示通用的、固定长度的原始二进制数据缓冲区
将字符串转为字节的方法

实战地址

uniapp vue3 + ts 微信小程序, 参考自wx-formdata

知识点解析

formData

在请求的头部,可以看到如下内容

content-type: multipart/form-data; boundary=----WebKitFormBoundaryWcr2rjV9uCpBU8Ah
  1. multipart/form-data: 指定传输数据位二进制类型
  2. boundary: 字符串 ----WebKitFormBoundary + 随机16个大小写字母或数字
  3. 查看Http请求的负载可以看到,formData的大致解构如下
Content-Disposition: form-data; name=\"name\"

Chaos
------WebKitFormBoundaryWcr2rjV9uCpBU8Ah
Content-Disposition: form-data; name=\"file\"; filename=\"javascript-736400_1280.png\"
Content-Type: image/png


------WebKitFormBoundaryWcr2rjV9uCpBU8Ah
Content-Disposition: form-data; name=\"file\"; filename=\"NloFA.png\"
Content-Type: image/png

<!-- 看不见的ArrayBuffer -->
------WebKitFormBoundaryWcr2rjV9uCpBU8Ah--

header中的boundary用于分割多个键值对,最后以\${boundary}--\\结束。以上整个内容需要以二进制的形式发送给后端.

关于文件,我们可以直接获取其二进制内容,剩下需要处理的就是把其他文本内容转为二进制.

ArrayBuffer 和 Uint8Array

通过FileSystemManager,可以获取到文件的二进制内容(ArrayBuffer).然后通过Uint8Array 以二进制的形式,拼接FormData的其他部分.

字符串转二进制

toUft8Bytes('字符串转二进制')

const toUtf8Bytes = (str: string) => {
  const bytes = [];
  for (var i = 0; i < str.length; i++) {
    bytes.push(...utf8CodeAt(str, i))

    const code = str.codePointAt(i) as number
    if (code > 0xffff) {
      i++;
    }
  }
  return bytes;
}
const utf8CodeAt = (str: string, i: number) => {
  var out = [], p = 0;
  var c = str.charCodeAt(i);
  if (c < 128) {
    out[p++] = c;
  } else if (c < 2048) {
    out[p++] = (c >> 6) | 192;
    out[p++] = (c & 63) | 128;
  } else if (
      ((c & 0xFC00) == 0xD800) && (i + 1) < str.length &&
      ((str.charCodeAt(i + 1) & 0xFC00) == 0xDC00)) {
    // Surrogate Pair
    c = 0x10000 + ((c & 0x03FF) << 10) + (str.charCodeAt(++i) & 0x03FF);
    out[p++] = (c >> 18) | 240;
    out[p++] = ((c >> 12) & 63) | 128;
    out[p++] = ((c >> 6) & 63) | 128;
    out[p++] = (c & 63) | 128;
  } else {
    out[p++] = (c >> 12) | 224;
    out[p++] = ((c >> 6) & 63) | 128;
    out[p++] = (c & 63) | 128;
  }
  return out;
}

总结

以上是关于小程序上传多文件的大致思路,但该方法有一个缺点,就是无法上传json对象.
可以将json转为字符然后后端处理一下,就是有点呆呆的.

提 交
暂无评论