Các atob
chức năng sẽ giải mã một chuỗi Base64 mã hóa thành một chuỗi mới với một ký tự cho mỗi byte của dữ liệu nhị phân.
const byteCharacters = atob(b64Data);
Mỗi điểm mã của ký tự (charCode) sẽ là giá trị của byte. Chúng ta có thể tạo một mảng các giá trị byte bằng cách áp dụng .charCodeAt
phương thức này bằng cách sử dụng phương thức cho từng ký tự trong chuỗi.
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
Bạn có thể chuyển đổi mảng giá trị byte này thành một mảng byte được gõ thực sự bằng cách chuyển nó đến hàm Uint8Array
tạo.
const byteArray = new Uint8Array(byteNumbers);
Đến lượt nó có thể được chuyển đổi thành BLOB bằng cách gói nó trong một mảng và chuyển nó đến hàm Blob
tạo.
const blob = new Blob([byteArray], {type: contentType});
Các mã trên hoạt động. Tuy nhiên, hiệu suất có thể được cải thiện một chút bằng cách xử lý các byteCharacters
lát nhỏ hơn thay vì tất cả cùng một lúc. Trong thử nghiệm thô của tôi, 512 byte dường như là một kích thước lát cắt tốt. Điều này cho chúng ta các chức năng sau đây.
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;
Ví dụ đầy đủ:
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);