Respuestas:
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 );
}
pero, las implementaciones no nativas son más rápidas, por ejemplo, https://gist.github.com/958841, consulte http://jsperf.com/encoding-xhr-image-data/6
join()
ponerlos al final es significativamente más rápido en Firefox, IE y Safari (pero mucho más lento en Chrome): jsperf.com/tobase64-implementations
Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.
Esto funciona bien para mi:
var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));
En ES6, la sintaxis es un poco más simple:
let base64String = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
Como se señaló en los comentarios, este método puede provocar un error de tiempo de ejecución en algunos navegadores cuando ArrayBuffer
es grande. El límite de tamaño exacto depende de la implementación en cualquier caso.
btoa([].reduce.call(new Uint8Array(bufferArray),function(p,c){return p+String.fromCharCode(c)},''))
btoa
es seguro para los caracteres en el rango de código 0-255, ya que este es el caso (piense en el 8 Uint8Array
).
Para aquellos a los que les gusta, este es otro Array.reduce
que no causará desbordamiento de pila:
var base64 = btoa(
new Uint8Array(arrayBuffer)
.reduce((data, byte) => data + String.fromCharCode(byte), '')
);
<amount of Bytes in the buffer>
nuevas cadenas.
btoa(new Uint8Array(arraybuffer).reduce((data,byte)=>(data.push(String.fromCharCode(byte)),data),[]).join(''))
?
Hay otra forma asincrónica de usar Blob y FileReader.
No probé el rendimiento. Pero es una forma 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]
lugar de dataurl.substr(dataurl.indexOf(',')+1)
.
readAsDataURL
podría teóricamente devolver un porcentaje de dataURI codificado (y parece que en realidad es el caso en jsdom )
split
mejor que substring
?
Usé esto y funciona para mí.
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;
}
Mi recomendación para esto es NO usar btoa
estrategias nativas , ya que no codifican correctamente todas ArrayBuffer
...
reescribe los DOM atob () y btoa ()
Dado que DOMStrings son cadenas codificadas de 16 bits, en la mayoría de los navegadores que llaman a window.btoa en una cadena Unicode, se generará una excepción de caracteres fuera del rango si un carácter excede el rango de un carácter codificado ASCII de 8 bits.
Si bien nunca he encontrado este error exacto, he descubierto que muchos de los ArrayBuffer
que he intentado codificar se han codificado incorrectamente.
Yo usaría la recomendación MDN o lo esencial.
btoa
no funciona en String, pero OP pregunta ArrayBuffer
.
var blob = new Blob([arrayBuffer])
var reader = new FileReader();
reader.onload = function(event){
var base64 = event.target.result
};
reader.readAsDataURL(blob);
A continuación se presentan 2 funciones simples para convertir Uint8Array a String Base64 y viceversa
arrayToBase64String(a) {
return btoa(String.fromCharCode(...a));
}
base64StringToArray(s) {
let asciiString = atob(s);
return new Uint8Array([...asciiString].map(char => char.charCodeAt(0)));
}
function
palabra clave y debería funcionar en un navegador moderno.
Puede derivar una matriz normal del ArrayBuffer
mediante Array.prototype.slice
. Utilice una función como Array.prototype.map
convertir bytes en caracteres y join
unirlos en forma de cadena.
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
}
Este método es más rápido ya que no hay concatenaciones de cadenas ejecutándose en él.
El OP no especificó el entorno de ejecución, pero si está utilizando Node.JS, hay una manera muy sencilla de hacerlo.
Acordar con los documentos oficiales de 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');
Además, si está ejecutando en Angular, por ejemplo, la clase de búfer también estará disponible en un entorno de navegador.
Javascript
. Así que actualicé mi respuesta para hacerlo más conciso. Creo que esta es una respuesta importante porque estaba buscando cómo hacer esto y no pude encontrar la mejor respuesta al problema.
A mi lado, usando el navegador Chrome, tuve que usar DataView () para leer un 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("");
}
Esto es mejor si usa JSZip para descomprimir el archivo de la cadena