Given a base64
string, what is the safest and most efficient way to create an ArrayBuffer
. Specifically a typeless array buffer in pure modern JavaScript.
The first SO result is this question from 2014. The accepted answer is
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;
}
It already assumes a type and there are ments which suggest that this is not always correct.
Is this still the best solution today? Do we have to iterate over all elements in a for loop? Is there a better and more efficient way using vanilla JS where we can pass a blob
of the string?
An example problem is processing a GLTF buffer which is provided as a base64
encoded string:
let str = 'data:application/octet-stream;base64,AAABAAIAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAA=';
This has two separate views of scalar (unsigned short) and vec3
(float) data, requiring further processing.
[edit]
So the most popular answer is not of use here as it creates a TypedArray
but the data in the base64
string does not represent a homogenous data set.
Given a base64
string, what is the safest and most efficient way to create an ArrayBuffer
. Specifically a typeless array buffer in pure modern JavaScript.
The first SO result is this question from 2014. The accepted answer is
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;
}
It already assumes a type and there are ments which suggest that this is not always correct.
Is this still the best solution today? Do we have to iterate over all elements in a for loop? Is there a better and more efficient way using vanilla JS where we can pass a blob
of the string?
An example problem is processing a GLTF buffer which is provided as a base64
encoded string:
let str = 'data:application/octet-stream;base64,AAABAAIAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAA=';
This has two separate views of scalar (unsigned short) and vec3
(float) data, requiring further processing.
[edit]
So the most popular answer is not of use here as it creates a TypedArray
but the data in the base64
string does not represent a homogenous data set.
- Your last line makes no sense at all. Is that left over from another post? Nowhere in your question is there anything about views, unsigned short, vec3 or float, and none of those things would seem to be Javascript concepts. – Tim Roberts Commented Nov 13, 2021 at 18:24
-
@TimRoberts The last line is to add context. The issue is that the most popular answer creates a
Uint8Array
and not a typelessArrayBuffer
on which further operations can be made. It's really to iterate that I don't want aTypedArray
because that will lock you into a single view of the binary data. – dubious Commented Nov 13, 2021 at 18:31
1 Answer
Reset to default 5Since your str
is a data:uri
, you might use fetch
:
let str = 'data:application/octet-stream;base64,AAABAAIAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAA=';
fetch(str)
.then(b => b.arrayBuffer())
.then(buff => console.log( new Int8Array(buff) /* just for a view purpose */ ))
.catch(e => console.log(e))