本文原文发布于我的博客 https:// eyhn.in
JavaScript 目前没有一个标准的方法可以将字符串转换为 ArrayBuffer。网络上流传的一些方法不能完美的处理 Unicode ,以下是一些方法可以安全在字符串与字节数组之间互相转换。
使用 Encoding API
大家似乎都不知道在 Web 平台早就有处理文本编码的方法规范,Firefox 和 Chrome 都完美支持,速度和实现肯定是最快最正确的,不仅仅支持 Unicode
还可以处理 iso-8859-2
,koi8
,cp1261
,gbk
等其他编码格式。旧版本的 Edge 用不了很遗憾。
这里有一篇 来自 Google 的文章 介绍了如何使用 Encoding API 转换文本与 ArrayBuffer。
![d067d3014ea4226e87920a1d2a3d6e9f.png](https://i-blog.csdnimg.cn/blog_migrate/43042ce89290e4a1a6e702ae78e3ec84.jpeg)
使用 Node Buffer 类
Node 没有 Encoding API ,我们可以使用 Buffer 类替代。
// String => Buffer
let buf = Buffer.from(" ")
// Buffer => String
buf.toString()
使用原生 JS 方法
如果你想写跨平台的代码,可以使用以下的方法。
inexorabletash / text-encoding
这是一个 Encoding API 的 Polyfill ,实现了大部分的功能。核心功能(99.1 KB) + 非 Unicode 编码支持(518 KB)体积实在有点大。
MDN 上提供的 TextEncoder Polyfill
代码还蛮长的我就不贴过来了。直接兼容到 IE5。因为是 MDN 提供的比较放心。
我自己写的字符串转 ArrayBuffer
使用的是 codePointAt()
方法,支持 ES6 的浏览器都可以用。IE 兼容没有 MDN 的好,但是结果还是正确的。
function textToArrayBuffer(s: string) {
var i = s.length;
var n = 0;
var ba = new Array()
for (var j = 0; j < i;) {
var c = s.codePointAt(j);
if (c < 128) {
ba[n++] = c;
j++;
}
else if ((c > 127) && (c < 2048)) {
ba[n++] = (c >> 6) | 192;
ba[n++] = (c & 63) | 128;
j++;
}
else if ((c > 2047) && (c < 65536)) {
ba[n++] = (c >> 12) | 224;
ba[n++] = ((c >> 6) & 63) | 128;
ba[n++] = (c & 63) | 128;
j++;
}
else {
ba[n++] = (c >> 18) | 240;
ba[n++] = ((c >> 12) & 63) | 128;
ba[n++] = ((c >> 6) & 63) | 128;
ba[n++] = (c & 63) | 128;
j+=2;
}
}
return new Uint8Array(ba).buffer;
}
最后
如果你有其他好用的方法可以在评论里留言。经过测试以上所有方法都支持所有 Unicode 区域。