预备知识点
FormData: 将数据以键值对的方式,发送给HTTP请求
Uint8Array: 8位无符号整型数组(0-255),即字节数组
ArrayBuffer:对象用来表示通用的、固定长度的原始二进制数据缓冲区
将字符串转为字节的方法
实战地址
uniapp vue3 + ts 微信小程序, 参考自wx-formdata
知识点解析
formData
在请求的头部,可以看到如下内容
content-type: multipart/form-data; boundary=----WebKitFormBoundaryWcr2rjV9uCpBU8Ah
- multipart/form-data: 指定传输数据位二进制类型
- boundary: 字符串
----WebKitFormBoundary
+ 随机16个大小写字母或数字 - 查看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转为字符然后后端处理一下,就是有点呆呆的.
暂无评论