在处理 WebSocket 通信时,我们经常需要对数据进行编码和解码。一个常见的场景是接收到 base64 编码的字符串,将其解码为 Uint8Array 进行处理,然后再将处理后的 Uint8Array 编码为 base64 字符串发送回去。那么,如何在 JavaScript 中实现这个转换过程呢?
使用 TextDecoder
和 btoa
方法
如果你的数据包含多字节序列,并且浏览器支持 TextDecoder
,可以使用 TextDecoder
将 Uint8Array 解码为字符串,然后使用 btoa
将字符串编码为 base64。
示例代码:
var u8 = new Uint8Array([65, 66, 67, 68]);
var decoder = new TextDecoder('utf8');
var b64encoded = btoa(decoder.decode(u8));
console.log(b64encoded); // 输出: QUJDRA==
使用 String.fromCharCode
方法
如果你的数据仅包含纯 ASCII 字符(非多字节 Unicode/UTF-8),可以使用 String.fromCharCode
方法将 Uint8Array 转换为字符串,然后使用 btoa
进行 base64 编码。
示例代码:
var ascii = new Uint8Array([65, 66, 67, 68]);
var b64encoded = btoa(String.fromCharCode.apply(null, ascii));
console.log(b64encoded); // 输出: QUJDRA==
处理大数组
对于非常大的数组,使用 apply
方法可能会导致 “最大调用堆栈大小超出” 错误。此时需要将数组分块处理。
示例代码:
function Uint8ToString(u8a){
var CHUNK_SZ = 0x8000; // 每次处理的块大小
var c = [];
for (var i = 0; i < u8a.length; i += CHUNK_SZ) {
c.push(String.fromCharCode.apply(null, u8a.subarray(i, i + CHUNK_SZ)));
}
return c.join("");
}
// 使用示例
var u8 = new Uint8Array([65, 66, 67, 68]);
var b64encoded = btoa(Uint8ToString(u8));
console.log(b64encoded); // 输出: QUJDRA==
将 base64 字符串解码为 Uint8Array
如果需要将 base64 字符串解码为 Uint8Array,可以使用以下代码:
var b64encoded = 'QUJDRA==';
var u8_2 = new Uint8Array(atob(b64encoded).split("").map(function(c) {
return c.charCodeAt(0);
}));
console.log(u8_2); // 输出: Uint8Array(4) [ 65, 66, 67, 68 ]