ArrayBuffer与Blob

前后端数据交换在一些情况下需要传输大量数据(特别是文件上传/下载时),此处主要还是下载的场景。通常来说后端返回二进制数据流,前端可以指定响应头为 blob 或者 arraybuffer。通常来讲如果这个文件是需要下载的文件使用 blob 类型,然后前端创建一个 a 标签触发下载,在图像、音视频(流媒体)则会使用 arraybuffer 类型,然后前端在进行相应处理。

ArrayBuffer

ArrayBuffer 是 JavaScript 里用于表示二进制数据的底层数据结构,在处理二进制数据(像文件、网络请求、图像等)时非常实用。

ArrayBuffer 是一段固定长度的二进制数据缓冲区,在内存中以连续的字节序列形式存在。一旦创建,其长度便不可更改。不能直接操作 ArrayBuffer 中的数据,而是要通过视图(如 DataView、TypedArray)来对其进行读写操作。

Blob

在 JavaScript 中,Blob(Binary Large Object)对象代表了不可变的、原始数据的类文件对象。它与文件相似,但不一定来源于文件系统。

Blob 对象用来存储二进制数据,它可以包含文本、图片、音频、视频等各种类型的数据。它是不可变的,意味着一旦创建,其内容就不能被直接修改。

ArrayBuffer、Blob、Base64 互转

ArrayBuffer 转 Blob

1
2
3
4
5
6
const arrayBufferToBlob = function (
buffer: ArrayBuffer,
type: string = "application/octet-stream"
): Blob {
return new Blob([buffer], { type });
};

ArrayBuffer 转 Base64

1
2
3
4
const arrayBufferToBase64 = function (buffer: ArrayBuffer): string {
const binary = String.fromCharCode(...new Uint8Array(buffer));
return btoa(binary);
};

Blob 转 ArrayBuffer

1
2
3
const blobToArrayBuffer = async function (blob: Blob): Promise<ArrayBuffer> {
return await blob.arrayBuffer();
};

Blob 转 Base64

1
2
3
4
5
6
7
8
9
10
11
12
const blobToBase64 = async function (blob: Blob): Promise<string> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
const dataUrl = reader.result as string;
const base64 = dataUrl.split(",")[1];
resolve(base64);
};
reader.onerror = () => reject(reader.error);
reader.readAsDataURL(blob);
});
};

Base64 转 ArrayBuffer

1
2
3
4
5
6
7
8
const base64ToArrayBuffer = function (base64: string): ArrayBuffer {
const binaryString = atob(base64);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes.buffer;
};

Base64 转 Blob

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const base64ToBlob = function (
base64: string,
type: string = "application/octet-stream"
): Blob {
const byteCharacters = atob(base64);
const byteArrays = [];

for (let offset = 0; offset < byteCharacters.length; offset += 512) {
const slice = byteCharacters.slice(offset, offset + 512);
const byteNumbers = new Array(slice.length);

for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}

byteArrays.push(new Uint8Array(byteNumbers));
}
return new Blob(byteArrays, { type });
};

[越努力,越幸运!]