Jawaban:
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 );
}
tetapi, implementasi non-asli lebih cepat mis. https://gist.github.com/958841 lihat http://jsperf.com/encoding-xhr-image-data/6
join()
menambahkannya pada akhirnya secara signifikan lebih cepat pada Firefox, IE, dan Safari (tetapi lebih lambat pada Chrome): jsperf.com/tobase64-implementations
Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.
Ini berfungsi baik untuk saya:
var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));
Dalam ES6, sintaks sedikit lebih sederhana:
let base64String = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
Seperti yang ditunjukkan dalam komentar, metode ini dapat mengakibatkan kesalahan runtime di beberapa browser saat browser ArrayBuffer
berukuran besar. Batas ukuran yang tepat tergantung pada implementasi dalam hal apa pun.
btoa([].reduce.call(new Uint8Array(bufferArray),function(p,c){return p+String.fromCharCode(c)},''))
btoa
aman untuk karakter dalam rentang kode 0-255, karena ini masalahnya (Pikirkan tentang 8 in Uint8Array
).
Bagi mereka yang suka itu pendek, berikut ini menggunakan Array.reduce
yang lain yang tidak akan menyebabkan stack overflow:
var base64 = btoa(
new Uint8Array(arrayBuffer)
.reduce((data, byte) => data + String.fromCharCode(byte), '')
);
<amount of Bytes in the buffer>
string baru.
btoa(new Uint8Array(arraybuffer).reduce((data,byte)=>(data.push(String.fromCharCode(byte)),data),[]).join(''))
?
Ada cara asinkron lain menggunakan Blob dan FileReader.
Saya tidak menguji kinerja. Tetapi cara berpikirnya berbeda.
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]
sebagai ganti dataurl.substr(dataurl.indexOf(',')+1)
.
readAsDataURL
secara teoritis dapat mengembalikan persen data yang disandikanURI (Dan tampaknya itu sebenarnya kasus di jsdom )
split
lebih baik daripada substring
?
Saya menggunakan ini dan bekerja untuk saya.
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;
}
Rekomendasi saya untuk ini adalah BUKAN menggunakan btoa
strategi asli — karena mereka tidak benar menyandikan semua ArrayBuffer
...
tulis ulang DOM atob () dan btoa ()
Karena DOMStrings adalah string yang dikodekan 16-bit, di sebagian besar browser yang memanggil window.btoa pada string Unicode akan menyebabkan pengecualian Character Out Of Range jika karakter melebihi kisaran karakter yang dikodekan ASCII 8-bit.
Meskipun saya belum pernah menemukan kesalahan yang tepat ini, saya telah menemukan bahwa banyak dari yang ArrayBuffer
saya coba enkode telah disandikan secara salah.
Saya akan menggunakan rekomendasi atau intisari MDN.
btoa
tidak berfungsi pada String, tetapi OP bertanya ArrayBuffer
.
var blob = new Blob([arrayBuffer])
var reader = new FileReader();
reader.onload = function(event){
var base64 = event.target.result
};
reader.readAsDataURL(blob);
Di bawah ini adalah 2 fungsi sederhana untuk mengonversi Uint8Array ke Base64 String dan kembali lagi
arrayToBase64String(a) {
return btoa(String.fromCharCode(...a));
}
base64StringToArray(s) {
let asciiString = atob(s);
return new Uint8Array([...asciiString].map(char => char.charCodeAt(0)));
}
function
kata kunci dan itu harus berfungsi di browser modern.
Anda bisa mendapatkan array normal dari ArrayBuffer
menggunakan Array.prototype.slice
. Gunakan fungsi seperti Array.prototype.map
untuk mengkonversi byte ke karakter dan join
mereka bersama-sama untuk membentuk string.
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
}
Metode ini lebih cepat karena tidak ada rangkaian string yang berjalan di dalamnya.
OP tidak menentukan Running Enviroment tetapi jika Anda menggunakan Node.JS ada cara yang sangat sederhana untuk melakukan hal seperti itu.
Sesuai dengan dokumen Node.JS resmi 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');
Juga, Jika Anda menjalankan di bawah Angular misalnya, Kelas Buffer juga akan tersedia di Lingkungan Browser.
Javascript
. Jadi saya memperbarui jawaban saya untuk membuatnya lebih ringkas. Saya pikir ini adalah jawaban yang penting karena saya mencari cara untuk melakukan ini dan tidak bisa mendapatkan jawaban terbaik untuk masalah ini.
Di sebelah saya, menggunakan navigator Chrome, saya harus menggunakan DataView () untuk membaca 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("");
}
Ini lebih baik, jika Anda menggunakan JSZip untuk membongkar arsip dari string