ArrayBuffer到base64编码的字符串

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

346588 次浏览
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 < / p >

更新的基准测试: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(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从字符串解压缩存档,那么这样做会更好

对此,我的建议是不要使用本机btoa策略——因为它们不能正确地编码所有ArrayBuffer的…

重写dom atob()和btoa()

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

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

我会使用MDN推荐或gist。

还有另一种异步方式使用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"

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

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;
}
你可以使用Array.prototype.sliceArrayBuffer中派生一个普通数组。 使用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


}

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

对于那些喜欢简短的人,这里有另一个使用Array.reduce的函数,它不会导致堆栈溢出:

var base64 = btoa(
new Uint8Array(arrayBuffer)
.reduce((data, byte) => data + String.fromCharCode(byte), '')
);

下面是两个简单的函数,用于将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)));
}

在我身边,使用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;}
var blob = new Blob([arrayBuffer])


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


reader.readAsDataURL(blob);

OP没有指定运行环境,但如果你使用Node.JS,有一个非常简单的方法来做这件事。

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

// 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下运行,缓冲区类也会在浏览器环境中可用。

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

如果你愿意添加一个库,base64-arraybuffer:

yarn add base64-arraybuffer

然后:

  • encode(buffer)编码ArrayBuffer为base64字符串
  • decode(str) -解码base64字符串到ArrayBuffer
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建议的解决方案似乎很好。 但是在Node.js Btoa不支持

.js中

建议使用buffer.toString(encoding)

就像

const myString = buffer.toString("base64")

我使用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)