Yanıtlar:
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 );
}
ancak yerel olmayan uygulamalar daha hızlıdır, örneğin https://gist.github.com/958841 bkz. http://jsperf.com/encoding-xhr-image-data/6
join()
Firefox, IE ve Safari'de bir dizi karakter oluşturmak ve sonunda bunları yazmak daha hızlıdır (ancak Chrome'da çok daha yavaştır): jsperf.com/tobase64-implementations
Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.
Bu benim için iyi çalışıyor:
var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));
ES6'da sözdizimi biraz daha basittir:
let base64String = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
Yorumlarda belirtildiği gibi, bu yöntem ArrayBuffer
büyük olduğunda bazı tarayıcılarda bir çalışma zamanı hatasına neden olabilir . Kesin boyut sınırı her durumda uygulamaya bağlıdır.
btoa([].reduce.call(new Uint8Array(bufferArray),function(p,c){return p+String.fromCharCode(c)},''))
btoa
0-255 kod aralığındaki karakterler için güvenlidir, çünkü durum burada (8 inç'i düşünün Uint8Array
).
Kısa sevenler için, Array.reduce
yığın istifine neden olmayacak bir başka kullanım :
var base64 = btoa(
new Uint8Array(arrayBuffer)
.reduce((data, byte) => data + String.fromCharCode(byte), '')
);
<amount of Bytes in the buffer>
yeni dizeler oluşturuyorsunuz .
btoa(new Uint8Array(arraybuffer).reduce((data,byte)=>(data.push(String.fromCharCode(byte)),data),[]).join(''))
?
Blob ve FileReader'ı kullanmanın başka bir eşzamansız yolu var.
Performansı test etmedim. Fakat bu farklı bir düşünce biçimidir.
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]
kullanın dataurl.substr(dataurl.indexOf(',')+1)
.
readAsDataURL
teorik dataURI kodlanmış bir yüzde dönmek (Ve aslında olduğu görünüyor olabilir jsdom )
split
iyi substring
?
Bunu kullandım ve benim için çalışıyor.
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;
}
Bunun için tavsiyem, yerel btoa
stratejileri KULLANMAMAKTIR ;ArrayBuffer
…
atob () ve btoa () DOM'larını yeniden yazma
DOMStrings 16 bit kodlanmış dizeler olduğundan, bir Unicode dizesindeki window.btoa öğesini çağıran çoğu tarayıcıda, bir karakter 8 bit ASCII kodlu bir karakterin aralığını aşarsa Karakter Aralık Dışı İstisnasına neden olur.
Bu tam hatayla hiç karşılaşmamış ArrayBuffer
olsam da, kodlamaya çalıştığım birçok kodun yanlış kodlandığını gördüm.
Ben ya MDN tavsiye ya da gist kullanırsınız.
btoa
String üzerinde çalışmaz, ancak OP soruyor ArrayBuffer
.
var blob = new Blob([arrayBuffer])
var reader = new FileReader();
reader.onload = function(event){
var base64 = event.target.result
};
reader.readAsDataURL(blob);
Aşağıda Uint8Array'ı Base64 String'e ve tekrar geri dönüştürmek için 2 basit işlev bulunmaktadır
arrayToBase64String(a) {
return btoa(String.fromCharCode(...a));
}
base64StringToArray(s) {
let asciiString = atob(s);
return new Uint8Array([...asciiString].map(char => char.charCodeAt(0)));
}
function
Anahtar kelimeyi ekleyin, modern bir tarayıcıda çalışması gerekir.
ArrayBuffer
Kullanarak normal bir dizi türetebilirsiniz Array.prototype.slice
. Baytları Array.prototype.map
karakterlere ve join
bunları birlikte forma dizesine dönüştürmek gibi bir işlev kullanın .
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
}
Bu yöntem, içinde çalışan dize birleştirmeleri olmadığı için daha hızlıdır.
OP, Çalışan Ortamı belirtmedi, ancak Node.JS kullanıyorsanız böyle bir şey yapmanın çok basit bir yolu var.
Resmi Node.JS belgelerine uyum 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');
Ayrıca, örneğin Açısal altında çalıştırıyorsanız, Arabellek Sınıfı da Tarayıcı Ortamında kullanılabilir hale getirilir.
Javascript
. Bu yüzden cevabımı daha özlü hale getirmek için güncelledim. Bunun önemli bir cevap olduğunu düşünüyorum çünkü bunu nasıl yapacağımı araştırıyordum ve sorunun en iyi cevabını alamadım.
Yanımda, Chrome gezgin kullanarak, bir arrayBuffer okumak için DataView () kullanmak zorunda kaldım
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("");
}
Arşivi dizeden açmak için JSZip kullanıyorsanız bu daha iyidir