J'ai besoin d'un moyen efficace (en lecture native) pour convertir un ArrayBuffer en une chaîne base64 devant être utilisée sur un article multipart.
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 );
}
mais les implémentations non natives sont plus rapides, par exemple. https://Gist.github.com/958841 voir http://jsperf.com/encoding-xhr-image-data/6
Cela fonctionne bien pour moi:
var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));
Dans ES6, la syntaxe est un peu plus simple:
let base64String = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
Comme indiqué dans les commentaires, cette méthode peut entraîner une erreur d'exécution dans certains navigateurs lorsque ArrayBuffer est volumineux. La limite de taille exacte dépend dans tous les cas de la mise en œuvre.
Il existe une autre manière asynchrone d'utiliser Blob et FileReader.
Je n'ai pas testé la performance. Mais c'est une façon de penser différente.
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"
Pour ceux qui aiment ça, voici un autre en utilisant Array.reduce
qui ne causera pas de débordement de pile:
var base64 = btoa(
new Uint8Array(arrayBuffer)
.reduce((data, byte) => data + String.fromCharCode(byte), '')
);
Ma recommandation pour cela est de ne PAS utiliser les stratégies btoa
natives, car elles ne codent pas correctement tous les ArrayBuffer
…
réécrit les DOM atob () et btoa ()
Comme DOMStrings sont des chaînes codées sur 16 bits, dans la plupart des navigateurs, appeler window.btoa sur une chaîne Unicode provoquera une exception Caractère hors plage si un caractère dépasse la plage d'un caractère codé ASCII sur 8 bits.
Bien que je n’aie jamais rencontré cette erreur exacte, j’ai constaté que beaucoup des ArrayBuffer
que j’ai essayé de coder avaient mal codé.
Je voudrais soit utiliser la recommandation MDN ou Gist.
Je l'ai utilisé et travaille pour moi.
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;
}
Vous trouverez ci-dessous deux fonctions simples permettant de convertir Uint8Array en Base64 String et vice-versa.
arrayToBase64String(a) {
return btoa(String.fromCharCode(...a));
}
base64StringToArray(s) {
let asciiString = atob(s);
return new Uint8Array([...asciiString].map(char => char.charCodeAt(0)));
}
Vous pouvez dériver un tableau normal de ArrayBuffer
en utilisant Array.prototype.slice
. Utilisez une fonction comme Array.prototype.map
pour convertir les octets en caractères et join
ensemble pour former une chaîne.
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
}
Cette méthode est plus rapide car elle ne contient aucune concaténation de chaîne.
À mes côtés, en utilisant le navigateur Chrome, j'ai dû utiliser DataView () pour lire 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;}