URL đối tượng (Blob URL)
Các URL bắt đầu bằng tiền tố blob: được sử dụng để tham chiếu đến các đối tượng Blob. Thời gian sống của những URL này phụ thuộc vào tài liệu của cửa sổ đã tạo ra chúng.
const url = URL.createObjectURL(blob);
Chúng có thể được dùng trực tiếp trong thanh địa chỉ trình duyệt hoặc làm nguồn cho các phần tử như <img>, <iframe>, và <a>. Khi kết hợp với thuộc tính download của thẻ <a>, ta có thể kích hoạt hành vi tải xuống tệp.
Mã hóa Base64
Base64 là phương pháp biểu diễn dữ liệu nhị phân thông qua tập hợp gồm 64 ký tự có thể in được.
Lợi ích
- Dễ dàng truyền và xử lý dữ liệu dưới dạng văn bản thuần túy.
Hàm hỗ trợ
btoa(): Chuyển chuỗi thành chuỗi Base64.atob(): Giải mã một chuỗi Base64 trở lại dạng gốc.
btoa("JavaScript"); // 'SmF2YVNjcmlwdA=='
atob('SmF2YVNjcmlwdA=='); // 'JavaScript'
Data URL
Data URL có định dạng data:[loại MIME];base64, và chứa nội dung tệp được mã hóa dưới dạng chuỗi Base64 bên trong chính URL đó.
Data URL có thể được sử dụng tương tự như Blob URL — ví dụ trong các thẻ <img>, <iframe>, <a>, hay trong CSS như giá trị background-image.
Nhược điểm
- Kích thước sau khi mã hóa tăng khoảng 33% so với dữ liệu gốc.
- Không được lưu trữ trong bộ nhớ cache của trình duyệt, dẫn đến việc phải tải lại mỗi lần truy cập.
- Tốn nhiều tài nguyên hơn đáng kể khi hiển thị: tiêu thụ thêm ~53% CPU, gấp 4 lần RAM và chậm hơn 24.6 lần so với hình ảnh bình thường[^1].
Sử dụng đối tượng Image
const imageElement = new Image();
imageElement.src = blobURL || dataURL;
imageElement.onload = onLoadHandler;
Các phương thức Canvas
drawImage(image, dx, dy): Vẽ đối tượngImagelên canvas.putImageData(imageData, dx, dy): Đưa dữ liệu pixel từImageDatalên canvas.getImageData(sx, sy, sw, sh): Trích xuất vùng dữ liệu hình ảnh từ canvas trả vềImageData.toDataURL(type, quality): Xuất canvas thành chuỗi Data URL.toBlob(callback, type, quality): Xuất canvas thành đối tượng Blob bất đồng bộ.
Chuyển đổi giữa các định dạng dữ liệu
ArrayBuffer → Blob
const blobFromBuffer = new Blob([new Uint8Array(buffer, offset, length)]);
ArrayBuffer → Base64
const base64String = btoa(
String.fromCodePoint(...new Uint8Array(arrayBuffer))
);
Base64 → Blob
function convertBase64ToBlob(base64, mimeType = '', chunkSize = 512) {
const binaryStr = atob(base64);
const chunks = [];
for (let i = 0; i < binaryStr.length; i += chunkSize) {
const segment = binaryStr.slice(i, i + chunkSize);
const bytes = [...segment].map(char => char.charCodeAt(0));
chunks.push(new Uint8Array(bytes));
}
return new Blob(chunks, { type: mimeType });
}
Blob → ArrayBuffer
async function readBlobAsArrayBuffer(blobFile) {
const reader = new FileReader();
return new Promise((resolve, reject) => {
reader.onload = () => resolve(reader.result);
reader.onerror = reject;
reader.readAsArrayBuffer(blobFile);
});
}
Blob → Base64
async function getBase64FromBlob(blobFile) {
const reader = new FileReader();
return new Promise(resolve => {
reader.onloadend = () => resolve(reader.result.split(',')[1]);
reader.readAsDataURL(blobFile);
});
}
Blob → Object URL
const objUrl = URL.createObjectURL(blobInstance);
Blob ↔ File
// Blob sang File
const fileObj = new File([blobData], "sample.txt", { type: "text/plain" });
// File sang Blob
const blobObj = new Blob([fileInput], { type: fileInput.type });