La atob
fonction décode une chaîne encodée en Base64 en une nouvelle chaîne avec un caractère pour chaque octet des données binaires.
const byteCharacters = atob(b64Data);
Le point de code de chaque caractère (charCode) sera la valeur de l'octet. Nous pouvons créer un tableau de valeurs d'octets en appliquant ceci en utilisant la .charCodeAt
méthode pour chaque caractère de la chaîne.
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
Vous pouvez convertir ce tableau de valeurs d'octets en un tableau d'octets typé réel en le passant au Uint8Array
constructeur.
const byteArray = new Uint8Array(byteNumbers);
Celui-ci peut à son tour être converti en BLOB en l'enveloppant dans un tableau et en le transmettant au Blob
constructeur.
const blob = new Blob([byteArray], {type: contentType});
Le code ci-dessus fonctionne. Cependant, les performances peuvent être améliorées un peu en traitant les byteCharacters
plus petites tranches, plutôt que toutes à la fois. Dans mes tests approximatifs, 512 octets semblent être une bonne taille de tranche. Cela nous donne la fonction suivante.
const b64toBlob = (b64Data, contentType='', sliceSize=512) => {
const byteCharacters = atob(b64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, {type: contentType});
return blob;
}
const blob = b64toBlob(b64Data, contentType);
const blobUrl = URL.createObjectURL(blob);
window.location = blobUrl;
Exemple complet:
const b64toBlob = (b64Data, contentType='', sliceSize=512) => {
const byteCharacters = atob(b64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, {type: contentType});
return blob;
}
const contentType = 'image/png';
const b64Data = 'iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';
const blob = b64toBlob(b64Data, contentType);
const blobUrl = URL.createObjectURL(blob);
const img = document.createElement('img');
img.src = blobUrl;
document.body.appendChild(img);