Reputation: 1746
Our app downloads a zip file, but the response is in binary.
So what I did is to convert it to base64. It works when the size is 87.7KB
but an error occurs when the response size is 183KB
.
The error is Uncaught RangeError: Maximum call stack size exceeded
The line in question is
btoa(String.fromCharCode.apply(null, new Uint8Array(blob)))
According to this answer, the String.fromCharCode.apply()
must be replaced with TextEncoder
.
So I changed it to
btoa(new TextDecoder('utf-8').decode(new Uint8Array(blob)))
but I get an error.
Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.
I changed it again using the top most snippet of this answer
The new code is now
btoa(unescape(encodeURIComponent(new TextDecoder('utf-8').decode(new Uint8Array(blob)))))
The download now works but the download zip file is corrupted.
The whole code can be seen here
Upvotes: 19
Views: 12387
Reputation: 35
https://stackoverflow.com/a/40077712/6582356
function blobToB64(data) {
if ('TextDecoder' in window) {
// Decode as UTF-8
var dataView = new DataView(data);
var decoder = new TextDecoder('utf8');
return btoa(decoder.decode(dataView));
} else {
// Fallback
return btoa(new Uint8Array(data).reduce((data, byte) =>
data + String.fromCharCode(byte),
''))
}
}
https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder
This one is seems to have better performance
Upvotes: -2