La atob
funzione decodificherà una stringa codificata Base64 in una nuova stringa con un carattere per ogni byte dei dati binari.
const byteCharacters = atob(b64Data);
Il punto di codice di ciascun carattere (charCode) sarà il valore del byte. Siamo in grado di creare una matrice di valori byte applicando questo utilizzando il .charCodeAt
metodo per ciascun carattere nella stringa.
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
È possibile convertire questo array di valori di byte in un array di byte tipizzato reale passandolo al Uint8Array
costruttore.
const byteArray = new Uint8Array(byteNumbers);
Questo a sua volta può essere convertito in un BLOB avvolgendolo in un array e passandolo al Blob
costruttore.
const blob = new Blob([byteArray], {type: contentType});
Il codice sopra funziona. Tuttavia, le prestazioni possono essere leggermente migliorate elaborando le byteCharacters
sezioni più piccole, piuttosto che tutte in una volta. Nel mio test approssimativo 512 byte sembrano essere una buona dimensione della fetta. Questo ci dà la seguente funzione.
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;
Esempio completo:
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);