268

我需要一种有效的(读取本机)方法来将一个转换为ArrayBuffer需要在多部分帖子上使用的 base64 字符串。

4

14 回答 14

284
function _arrayBufferToBase64( buffer ) {
    var binary = '';
    var bytes = new Uint8Array( buffer );
    var len = bytes.byteLength;
    for (var i = 0; i < len; i++) {
        binary += String.fromCharCode( bytes[ i ] );
    }
    return window.btoa( binary );
}

但是,非本地实现更快,例如https://gist.github.com/958841 参见http://jsperf.com/encoding-xhr-image-data/6

更新的基准:https ://jsben.ch/wnaZC

于 2012-02-27T01:29:02.580 回答
143

这对我来说很好:

var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));

在 ES6 中,语法稍微简单一些:

const base64String = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));

正如评论中所指出的,当ArrayBuffer较大时,此方法可能会导致某些浏览器出现运行时错误。在任何情况下,确切的大小限制都取决于实现。

于 2012-07-19T14:02:01.130 回答
51

对于那些喜欢简短的人来说,这是另一个Array.reduce不会导致堆栈溢出的用法:

var base64 = btoa(
  new Uint8Array(arrayBuffer)
    .reduce((data, byte) => data + String.fromCharCode(byte), '')
);
于 2017-02-19T23:56:25.640 回答
42

还有另一种异步方式使用 Blob 和 FileReader。

我没有测试性能。但这是一种不同的思维方式。

function arrayBufferToBase64( buffer, callback ) {
    var blob = new Blob([buffer],{type:'application/octet-binary'});
    var reader = new FileReader();
    reader.onload = function(evt){
        var dataurl = evt.target.result;
        callback(dataurl.substr(dataurl.indexOf(',')+1));
    };
    reader.readAsDataURL(blob);
}

//example:
var buf = new Uint8Array([11,22,33]);
arrayBufferToBase64(buf, console.log.bind(console)); //"CxYh"
于 2016-07-10T10:52:09.223 回答
24
var blob = new Blob([arrayBuffer])

var reader = new FileReader();
reader.onload = function(event){
   var base64 =   event.target.result
};

reader.readAsDataURL(blob);
于 2019-10-11T10:32:32.970 回答
17

我使用了它并为我工作。

function arrayBufferToBase64( buffer ) {
    var binary = '';
    var bytes = new Uint8Array( buffer );
    var len = bytes.byteLength;
    for (var i = 0; i < len; i++) {
        binary += String.fromCharCode( bytes[ i ] );
    }
    return window.btoa( binary );
}



function base64ToArrayBuffer(base64) {
    var binary_string =  window.atob(base64);
    var len = binary_string.length;
    var bytes = new Uint8Array( len );
    for (var i = 0; i < len; i++)        {
        bytes[i] = binary_string.charCodeAt(i);
    }
    return bytes.buffer;
}
于 2016-08-09T18:38:48.180 回答
15

下面是 2 个简单的函数,用于将 Uint8Array 转换为 Base64 字符串并再次转换回来

arrayToBase64String(a) {
    return btoa(String.fromCharCode(...a));
}

base64StringToArray(s) {
    let asciiString = atob(s);
    return new Uint8Array([...asciiString].map(char => char.charCodeAt(0)));
}
于 2017-07-25T21:33:04.660 回答
14

我对此的建议是不要使用原生btoa策略——因为它们不能正确编码所有ArrayBuffer的 's...</p>

重写 DOM atob() 和 btoa()

由于 DOMStrings 是 16 位编码的字符串,因此在大多数浏览器中,如果字符超出 8 位 ASCII 编码字符的范围,则对 Unicode 字符串调用 window.btoa 将导致字符超出范围异常。

虽然我从未遇到过这个确切的错误,但我发现ArrayBuffer我尝试编码的许多 's 编码不正确。

我会使用 MDN 推荐或要点。

于 2015-07-25T00:15:18.753 回答
10

OP 没有指定运行环境,但是如果您使用的是 Node.JS,那么有一种非常简单的方法可以做到这一点。

与官方 Node.JS 文档一致 https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings

// This step is only necessary if you don't already have a Buffer Object
const buffer = Buffer.from(yourArrayBuffer);

const base64String = buffer.toString('base64');

此外,例如,如果您在 Angular 下运行,缓冲区类也将在浏览器环境中可用。

于 2020-02-20T13:54:12.677 回答
5

如果您可以添加库,base64-arraybuffer

yarn add base64-arraybuffer

然后:

  • encode(buffer)- 将 ArrayBuffer 编码为 base64 字符串
  • decode(str)- 将 base64 字符串解码为 ArrayBuffer
于 2021-06-05T19:54:43.110 回答
0

您可以ArrayBuffer使用Array.prototype.slice. 使用类似Array.prototype.map将字节转换为字符并将join它们一起形成字符串的函数。

function arrayBufferToBase64(ab){

    var dView = new Uint8Array(ab);   //Get a byte view        

    var arr = Array.prototype.slice.call(dView); //Create a normal array        

    var arr1 = arr.map(function(item){        
      return String.fromCharCode(item);    //Convert
    });

    return window.btoa(arr1.join(''));   //Form a string

}

此方法更快,因为其中没有运行字符串连接。

于 2016-12-08T05:02:23.473 回答
-1

使用uint8-to-b64包在浏览器和 Node.js 中进行编码/解码

于 2021-03-30T19:39:31.840 回答
-4

在我身边,使用 Chrome 导航器,我不得不使用 DataView() 来读取 arrayBuffer

function _arrayBufferToBase64( tabU8A ) {
var binary = '';
let lecteur_de_donnees = new DataView(tabU8A);
var len = lecteur_de_donnees.byteLength;
var chaine = '';
var pos1;
for (var i = 0; i < len; i++) {
    binary += String.fromCharCode( lecteur_de_donnees.getUint8( i ) );
}
chaine = window.btoa( binary )
return chaine;}
于 2019-02-06T21:17:08.927 回答
-6
function _arrayBufferToBase64(uarr) {
    var strings = [], chunksize = 0xffff;
    var len = uarr.length;

    for (var i = 0; i * chunksize < len; i++){
        strings.push(String.fromCharCode.apply(null, uarr.subarray(i * chunksize, (i + 1) * chunksize)));
    }

    return strings.join("");
}

如果您使用 JSZip 从字符串中解压缩存档,这会更好

于 2015-07-23T17:11:40.217 回答