Risposte:
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 );
}
ma le implementazioni non native sono più veloci, ad es. https://gist.github.com/958841 consultare http://jsperf.com/encoding-xhr-image-data/6
join()
ingenerarli alla fine sia significativamente più veloce su Firefox, IE e Safari (ma molto più lentamente su Chrome): jsperf.com/tobase64-implementations
Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.
Questo funziona bene per me:
var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));
In ES6, la sintassi è un po 'più semplice:
let base64String = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
Come sottolineato nei commenti, questo metodo può causare un errore di runtime in alcuni browser quando ArrayBuffer
è grande. Il limite esatto di dimensione dipende comunque dall'implementazione.
btoa([].reduce.call(new Uint8Array(bufferArray),function(p,c){return p+String.fromCharCode(c)},''))
btoa
è sicuro per i caratteri nell'intervallo di codici 0-255, poiché questo è il caso (pensate agli 8 pollici Uint8Array
).
Per coloro a cui piace in breve, eccone un altro Array.reduce
che non causerà l'overflow dello stack:
var base64 = btoa(
new Uint8Array(arrayBuffer)
.reduce((data, byte) => data + String.fromCharCode(byte), '')
);
<amount of Bytes in the buffer>
nuove stringhe.
btoa(new Uint8Array(arraybuffer).reduce((data,byte)=>(data.push(String.fromCharCode(byte)),data),[]).join(''))
?
Esiste un altro modo asincrono di utilizzare BLOB e FileReader.
Non ho testato le prestazioni. Ma è un modo diverso di pensare.
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]
invece di dataurl.substr(dataurl.indexOf(',')+1)
.
readAsDataURL
potrebbe teoricamente restituire un dato codificato in percentualeURI (E sembra che sia effettivamente il caso in jsdom )
split
meglio di substring
?
L'ho usato e funziona per me.
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;
}
La mia raccomandazione per questo è di NON utilizzare nativo btoa
strategie , poiché non codificano correttamente tutteArrayBuffer
...
riscrivere i DOM atob () e btoa ()
Poiché DOMStrings sono stringhe con codifica a 16 bit, nella maggior parte dei browser che chiamano window.btoa su una stringa Unicode genererà un'eccezione Carattere fuori intervallo se un carattere supera l'intervallo di un carattere con codifica ASCII a 8 bit.
Anche se non ho mai riscontrato questo errore esatto, ho scoperto che molti dei ArrayBuffer
che ho provato a codificare hanno codificato in modo errato.
Vorrei utilizzare la raccomandazione MDN o sostanza.
btoa
non funziona su String, ma OP sta chiedendo ArrayBuffer
.
var blob = new Blob([arrayBuffer])
var reader = new FileReader();
reader.onload = function(event){
var base64 = event.target.result
};
reader.readAsDataURL(blob);
Di seguito sono riportate 2 semplici funzioni per convertire Uint8Array in Base64 String e viceversa
arrayToBase64String(a) {
return btoa(String.fromCharCode(...a));
}
base64StringToArray(s) {
let asciiString = atob(s);
return new Uint8Array([...asciiString].map(char => char.charCodeAt(0)));
}
function
parola chiave e dovrebbe funzionare in un browser moderno.
È possibile derivare un array normale ArrayBuffer
da usando Array.prototype.slice
. Utilizzare una funzione come Array.prototype.map
convertire i byte in caratteri e join
insieme in stringa forma.
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
}
Questo metodo è più veloce poiché non ci sono concatenazioni di stringhe in esecuzione in esso.
L'OP non ha specificato l'ambiente in esecuzione ma se si utilizza Node.JS esiste un modo molto semplice per eseguire tale operazione.
Secondo i documenti ufficiali di 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');
Inoltre, se si esegue ad esempio in Angular, la classe buffer sarà resa disponibile anche in un ambiente browser.
Javascript
. Quindi ho aggiornato la mia risposta per renderla più concisa. Penso che questa sia una risposta importante perché stavo cercando come farlo e non sono riuscito a ottenere la migliore risposta al problema.
Al mio fianco, usando Chrome Navigator, ho dovuto usare DataView () per leggere 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("");
}
Questo è meglio se usi JSZip per decomprimere l'archivio dalla stringa