我需要一个有效的(读本机)方法来转换一个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

其他回答

你可以使用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

}

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

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从字符串解压缩存档,那么这样做会更好

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

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

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

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

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