Antworten:
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 );
}
Nicht native Implementierungen sind jedoch schneller, z. B. https://gist.github.com/958841, siehe http://jsperf.com/encoding-xhr-image-data/6
Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.
Das funktioniert gut für mich:
var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));
In ES6 ist die Syntax etwas einfacher:
let base64String = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
Wie in den Kommentaren erwähnt, kann diese Methode in einigen Browsern zu einem Laufzeitfehler führen, wenn der ArrayBuffer
groß ist. Die genaue Größenbeschränkung ist in jedem Fall implementierungsabhängig.
btoa([].reduce.call(new Uint8Array(bufferArray),function(p,c){return p+String.fromCharCode(c)},''))
btoa
ist sicher für Zeichen im Codebereich 0-255, da dies hier der Fall ist (Denken Sie an die 8 Zoll Uint8Array
).
Für diejenigen, die es kurz mögen, ist hier eine andere, Array.reduce
die keinen Stapelüberlauf verursacht:
var base64 = btoa(
new Uint8Array(arrayBuffer)
.reduce((data, byte) => data + String.fromCharCode(byte), '')
);
<amount of Bytes in the buffer>
neue Zeichenfolgen.
btoa(new Uint8Array(arraybuffer).reduce((data,byte)=>(data.push(String.fromCharCode(byte)),data),[]).join(''))
?
Es gibt eine andere asynchrone Möglichkeit, Blob und FileReader zu verwenden.
Ich habe die Leistung nicht getestet. Aber es ist eine andere Denkweise.
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]
anstelle von dataurl.substr(dataurl.indexOf(',')+1)
.
readAsDataURL
könnte theoretisch ein Prozent der codierten Daten zurückgegeben werdenURUR (und es scheint, dass dies in jsdom tatsächlich der Fall ist )
split
besser als substring
?
Ich habe das benutzt und arbeite für mich.
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;
}
Meine Empfehlung hierfür ist, KEINE nativen btoa
Strategien zu verwenden, da diese nicht alle ArrayBuffer
…
Schreiben Sie die DOMs atob () und btoa () neu.
Da es sich bei DOMStrings um 16-Bit-codierte Zeichenfolgen handelt, führt in den meisten Browsern, die window.btoa für eine Unicode-Zeichenfolge aufrufen, eine Ausnahme für Zeichen außerhalb des Bereichs aus, wenn ein Zeichen den Bereich eines 8-Bit-ASCII-codierten Zeichens überschreitet.
Obwohl ich diesen genauen Fehler noch nie festgestellt habe, habe ich festgestellt, dass viele der von ArrayBuffer
mir versuchten Codierungen falsch codiert wurden.
Ich würde entweder die MDN-Empfehlung oder das Wesentliche verwenden.
btoa
funktioniert nicht mit String, aber OP fragt ArrayBuffer
.
var blob = new Blob([arrayBuffer])
var reader = new FileReader();
reader.onload = function(event){
var base64 = event.target.result
};
reader.readAsDataURL(blob);
Im Folgenden finden Sie zwei einfache Funktionen zum Konvertieren von Uint8Array in Base64 String und wieder zurück
arrayToBase64String(a) {
return btoa(String.fromCharCode(...a));
}
base64StringToArray(s) {
let asciiString = atob(s);
return new Uint8Array([...asciiString].map(char => char.charCodeAt(0)));
}
function
Schlüsselwort hinzu und es sollte in einem modernen Browser funktionieren.
Sie können ein normales Array aus dem ableiten, ArrayBuffer
indem Sie verwenden Array.prototype.slice
. Verwenden Sie eine Funktion Array.prototype.map
, um Bytes in Zeichen umzuwandeln und join
diese zusammen in eine Zeichenfolge umzuwandeln .
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
}
Diese Methode ist schneller, da keine Zeichenfolgenverkettungen ausgeführt werden.
Das OP hat die laufende Umgebung nicht angegeben, aber wenn Sie Node.JS verwenden, gibt es eine sehr einfache Möglichkeit, dies zu tun.
In Übereinstimmung mit den offiziellen Node.JS-Dokumenten 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');
Wenn Sie beispielsweise unter Angular ausgeführt werden, wird die Pufferklasse auch in einer Browserumgebung verfügbar gemacht.
Javascript
. Deshalb habe ich meine Antwort aktualisiert, um sie präziser zu gestalten. Ich denke, dies ist eine wichtige Antwort, da ich nach einer Möglichkeit gesucht habe und nicht die beste Antwort auf das Problem finden konnte.
An meiner Seite musste ich mit Chrome Navigator DataView () verwenden, um einen ArrayBuffer zu lesen
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("");
}
Dies ist besser, wenn Sie JSZip zum Entpacken des Archivs aus einer Zeichenfolge verwenden