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 ArrayBuffer
tamanho é 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.reduce
que 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 )
split
seria 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 btoa
estraté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.
btoa
nã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)));
}
function
palavra-chave e ela deverá funcionar em um navegador moderno.
Você pode derivar uma matriz normal do ArrayBuffer
usando Array.prototype.slice
. Use uma função como Array.prototype.map
converter bytes em caracteres e join
eles 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