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


当前回答

我的建议是不要使用原生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

其他回答

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

这对我来说很有效:

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

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

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

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

我用了这个,对我很有用。

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;
}

我使用TextDecode api将其转换为普通文本,然后将其转换为Base64

const uint =  new Uint8Array([ 73, 32, 108, 111, 118, 101, 32, 121, 111, 117 ]).buffer
const decoder = new TextDecoder()
const decodedText = decoder.decode(uint)
const base64Code = btoa(decodedText)
const blob = new Blob([array]);        
const reader = new FileReader();

reader.onload = (event) => {
  const dataUrl = event.target.result;
  const [_, base64] = dataUrl.split(','); 
  // do something with base64
};
   
reader.readAsDataURL(blob);

或作为一种许诺的效用:

async function encode(array) {
  return new Promise((resolve) => {
    const blob = new Blob([array]);
    const reader = new FileReader();
    
    reader.onload = (event) => {
      const dataUrl = event.target.result;
      const [_, base64] = dataUrl.split(',');
      
      resolve(base64);
    };
    
    reader.readAsDataURL(blob);
  });
}

const encoded = await encode(typedArray);