Câu trả lời:
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 );
}
tuy nhiên, việc triển khai không phải là bản địa nhanh hơn, ví dụ: https://gist.github.com/958841 xem http://jsperf.com/encoding-xhr-image-data/6
join()
đưa chúng vào cuối nhanh hơn đáng kể trên Firefox, IE và Safari (nhưng chậm hơn rất nhiều trên Chrome): jsperf.com/tobase64-im THỰCations
Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.
Cái này làm việc tốt cho tôi:
var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));
Trong ES6, cú pháp đơn giản hơn một chút:
let base64String = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
Như đã chỉ ra trong các ý kiến, phương pháp này có thể dẫn đến lỗi thời gian chạy trong một số trình duyệt khi ArrayBuffer
lớn. Giới hạn kích thước chính xác là phụ thuộc vào việc thực hiện trong mọi trường hợp.
btoa([].reduce.call(new Uint8Array(bufferArray),function(p,c){return p+String.fromCharCode(c)},''))
btoa
an toàn cho các ký tự trong phạm vi mã 0-255, vì đây là trường hợp (Hãy nghĩ về 8 in Uint8Array
).
Đối với những người thích nó ngắn, đây là một cái khác sử dụng Array.reduce
sẽ không gây ra lỗi tràn ngăn xếp:
var base64 = btoa(
new Uint8Array(arrayBuffer)
.reduce((data, byte) => data + String.fromCharCode(byte), '')
);
<amount of Bytes in the buffer>
chuỗi mới.
btoa(new Uint8Array(arraybuffer).reduce((data,byte)=>(data.push(String.fromCharCode(byte)),data),[]).join(''))
?
Có một cách không đồng bộ khác là sử dụng Blob và FileReader.
Tôi đã không kiểm tra hiệu suất. Nhưng đó là một cách nghĩ khác.
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]
thay vì dataurl.substr(dataurl.indexOf(',')+1)
.
readAsDataURL
về mặt lý thuyết có thể trả về một phần trăm dữ liệu được mã hóaURI (Và có vẻ như đó thực sự là trường hợp trong jsdom )
split
tốt hơn substring
?
Tôi đã sử dụng nó và làm việc cho tôi.
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;
}
Tôi đề nghị cho điều này là không nên sử dụng bản địa btoa
chiến lược-như họ không mã hóa một cách chính xác tất cả các ArrayBuffer
's ...
viết lại các DOM atob () và btoa ()
Do DOMStrings là các chuỗi được mã hóa 16 bit, nên trong hầu hết các trình duyệt gọi window.btoa trên chuỗi Unicode sẽ gây ra ngoại lệ Ký tự ngoài phạm vi nếu một ký tự vượt quá phạm vi của ký tự được mã hóa ASCII 8 bit.
Mặc dù tôi chưa bao giờ gặp phải lỗi chính xác này, tôi đã phát hiện ra rằng nhiều lỗi ArrayBuffer
tôi đã cố mã hóa đã mã hóa không chính xác.
Tôi sẽ sử dụng khuyến nghị MDN hoặc ý chính.
btoa
không hoạt động trên String, nhưng OP đang hỏi ArrayBuffer
.
var blob = new Blob([arrayBuffer])
var reader = new FileReader();
reader.onload = function(event){
var base64 = event.target.result
};
reader.readAsDataURL(blob);
Dưới đây là 2 chức năng đơn giản để chuyển đổi Uint8Array thành Chuỗi Base64 và quay lại lần nữa
arrayToBase64String(a) {
return btoa(String.fromCharCode(...a));
}
base64StringToArray(s) {
let asciiString = atob(s);
return new Uint8Array([...asciiString].map(char => char.charCodeAt(0)));
}
function
từ khóa và nó sẽ hoạt động trong một trình duyệt hiện đại.
Bạn có thể lấy được một mảng bình thường từ ArrayBuffer
bằng cách sử dụng Array.prototype.slice
. Sử dụng một hàm như Array.prototype.map
để chuyển đổi byte thành ký tự và join
chúng cùng nhau để tạo thành chuỗi.
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
}
Phương pháp này nhanh hơn vì không có chuỗi nối nào chạy trong nó.
OP không chỉ định Môi trường chạy nhưng nếu bạn đang sử dụng Node.JS thì có một cách rất đơn giản để làm việc đó.
Accordig với các tài liệu chính thức của Node.JS https://nodejs.org/api/buffer.html#buffer_buffftimeand_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');
Ngoài ra, nếu bạn đang chạy trong Angular chẳng hạn, Lớp đệm cũng sẽ được cung cấp trong Môi trường trình duyệt.
Javascript
. Vì vậy, tôi đã cập nhật câu trả lời của mình để làm cho nó ngắn gọn hơn. Tôi nghĩ rằng đây là một câu trả lời quan trọng bởi vì tôi đã tìm kiếm cách làm điều này và không thể có được câu trả lời tốt nhất cho vấn đề.
Ở bên cạnh tôi, bằng cách sử dụng trình điều hướng Chrome, tôi đã phải sử dụng DataView () để đọc một mảngBuffer
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("");
}
Điều này tốt hơn, nếu bạn sử dụng JSZip để giải nén tệp lưu trữ từ chuỗi