I need an efficient (read native) way to convert an ArrayBuffer
to a base64 string which needs to be used on a multipart post.
You can derive a normal array from the ArrayBuffer
by using Array.prototype.slice
.
Use a function like Array.prototype.map
to convert bytes in to characters and join
them together to forma 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
}
This method is faster since there are no string concatenations running in it.
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("");
}
This is better, if you use JSZip for unpack archive from string
var blob = new Blob([arrayBuffer])
var reader = new FileReader();
reader.onload = function(event){
var base64 = event.target.result
};
reader.readAsDataURL(blob);
The OP did not specify the Running Enviroment but if you are using Node.JS there is a very simple way to do such thing.
Accordig with the official Node.JS docs 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');
Also, If you are running under Angular for example, the Buffer Class will also be made available in a Browser Environment.
For those who like it short, here's an other one using Array.reduce
which will not cause stack overflow:
var base64 = btoa(
new Uint8Array(arrayBuffer)
.reduce((data, byte) => data + String.fromCharCode(byte), '')
);
This works fine for me:
var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));
In ES6, the syntax is a little simpler:
let base64String = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
As pointed out in the comments, this method may result in a runtime error in some browsers when the ArrayBuffer
is large. The exact size limit is implementation dependent in any case.