Respostas:
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 );
}
mas implementações não nativas são mais rápidas, por exemplo, https://gist.github.com/958841, consulte http://jsperf.com/encoding-xhr-image-data/6
join()ing-los no final é significativamente mais rápido no Firefox, IE e Safari (mas bastante mais lento no Chrome): jsperf.com/tobase64-implementations
Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.
Este trabalho é bom para mim:
var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));
No ES6, a sintaxe é um pouco mais simples:
let base64String = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
Conforme indicado nos comentários, esse método pode resultar em um erro de tempo de execução em alguns navegadores quando o ArrayBuffertamanho é grande. O limite exato de tamanho depende da implementação em qualquer caso.
btoa([].reduce.call(new Uint8Array(bufferArray),function(p,c){return p+String.fromCharCode(c)},''))
btoaé seguro para caracteres no intervalo de código de 0 a 255, pois esse é o caso (pense nos 8 pol Uint8Array.).
Para quem gosta de curtir, aqui está outro Array.reduceque não causará estouro de pilha:
var base64 = btoa(
new Uint8Array(arrayBuffer)
.reduce((data, byte) => data + String.fromCharCode(byte), '')
);
<amount of Bytes in the buffer>novas strings.
btoa(new Uint8Array(arraybuffer).reduce((data,byte)=>(data.push(String.fromCharCode(byte)),data),[]).join(''))?
Há outra maneira assíncrona de usar Blob e FileReader.
Eu não testei o desempenho. Mas é uma maneira diferente de pensar.
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"
dataurl.split(',', 2)[1]vez de dataurl.substr(dataurl.indexOf(',')+1).
readAsDataURL teoricamente poderia retornar um por cento codificado dataURI (E parece que é realmente o caso em jsdom )
splitseria melhor do que substring?
Eu usei isso e funciona para mim.
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;
}
Minha recomendação para isso é NÃO usar btoaestratégias nativas , pois elas não codificam corretamente todasArrayBuffer as…
reescreva os DOMs atob () e btoa ()
Como DOMStrings são cadeias de caracteres de 16 bits, na maioria dos navegadores que chamam window.btoa em uma cadeia de caracteres Unicode causará uma exceção de caracteres fora do intervalo se um caractere exceder o intervalo de um caractere de 8 bits codificado em ASCII.
Embora nunca tenha encontrado esse erro exato, descobri que muitos dos ArrayBuffer que tentei codificar foram codificados incorretamente.
Eu usaria recomendação MDN ou essência.
btoanão funciona em String, mas o OP está perguntando ArrayBuffer.
var blob = new Blob([arrayBuffer])
var reader = new FileReader();
reader.onload = function(event){
var base64 = event.target.result
};
reader.readAsDataURL(blob);
Abaixo estão 2 funções simples para converter Uint8Array em Base64 String e vice-versa
arrayToBase64String(a) {
return btoa(String.fromCharCode(...a));
}
base64StringToArray(s) {
let asciiString = atob(s);
return new Uint8Array([...asciiString].map(char => char.charCodeAt(0)));
}
functionpalavra-chave e ela deverá funcionar em um navegador moderno.
Você pode derivar uma matriz normal do ArrayBufferusando Array.prototype.slice. Use uma função como Array.prototype.mapconverter bytes em caracteres e joineles juntos para formar uma string.
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
}
Esse método é mais rápido, pois não há concatenações de strings em execução.
O OP não especificou o ambiente em execução, mas se você estiver usando o Node.JS, há uma maneira muito simples de fazer isso.
De acordo com os documentos oficiais do 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');
Além disso, se você estiver executando em Angular, por exemplo, a Classe Buffer também será disponibilizada em um Ambiente de Navegador.
Javascript. Atualizei minha resposta para torná-la mais concisa. Acho que essa é uma resposta importante, porque estava pesquisando como fazer isso e não consegui encontrar a melhor resposta para o problema.
Ao meu lado, usando o navegador Chrome, tive que usar o DataView () para ler um 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;}
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("");
}
Isso é melhor, se você usar JSZip para descompactar archive da string