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


当前回答

你可以使用array .prototype.slice从ArrayBuffer中派生一个普通数组。 使用像Array.prototype.map这样的函数将字节转换为字符并将它们连接在一起形成字符串。

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

}

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

其他回答

ABtoB64(ab) {
    return new Promise(res => {
        const fr = new FileReader();
        fr.onload = ({target: {result: s}}) => res(s.slice(s.indexOf(';base64,') + 8));
        fr.readAsDataURL(new Blob([ab]));
    });
}

异步方法使用文件阅读器。

我的建议是不要使用原生btoa策略——因为它们不能正确地编码所有ArrayBuffer的…

重写dom atob()和btoa()

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

虽然我从未遇到过这种确切的错误,但我发现我尝试编码的许多ArrayBuffer都编码错误。

我会使用MDN推荐或gist。

https://github.com/beatgammit/base64-js https://gist.github.com/jonleighton/958841

这对我来说很有效:

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

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

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

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

在我身边,使用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;}

下面是两个简单的函数,用于将Uint8Array转换为Base64 String

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

base64StringToArray(s) {
    let asciiString = atob(s);
    return new Uint8Array([...asciiString].map(char => char.charCodeAt(0)));
}