二进制数据操作从未如此简单! 掌握 Blob 对象,解锁前端文件处理超能力!⚡️
Blob(Binary Large Object)是 HTML5 提供的二进制数据容器,让你直接在浏览器中操作文件数据,无需服务器中转!🔧
一、图片 → Base64 → Blob 全流程 📸🔄
// 1. 图片转 Base64
function imageToBase64(img) {
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
return canvas.toDataURL('image/jpeg', 0.8); // 80%质量压缩
}
// 2. Base64 转 Blob
function base64ToBlob(base64, mimeType) {
// 剥离 Base64 前缀
const byteString = atob(base64.split(',')[1]);
// 创建 Uint8Array
const byteArray = new Uint8Array(byteString.length);
for (let i = 0; i < byteString.length; i++) {
byteArray[i] = byteString.charCodeAt(i);
}
// 生成 Blob
return new Blob([byteArray], { type: mimeType });
}
// 使用示例
const img = document.getElementById('myImage');
const base64 = imageToBase64(img);
const blob = base64ToBlob(base64, 'image/jpeg');
二、Blob 核心操作:切割与压缩 ✂️💾
// 1. 切割大文件(如分片上传)
const sliceBlob = (blob, chunkSize = 1024 * 1024) => {
const chunks = [];
let start = 0;
while (start < blob.size) {
chunks.push(blob.slice(start, start + chunkSize));
start += chunkSize;
}
return chunks;
};
// 2. 图片压缩(质量+尺寸)
async function compressImage(blob, maxWidth = 800, quality = 0.7) {
return new Promise((resolve) => {
const img = new Image();
const url = URL.createObjectURL(blob);
img.onload = () => {
const canvas = document.createElement('canvas');
const scale = maxWidth / img.width;
canvas.width = maxWidth;
canvas.height = img.height * scale;
canvas.getContext('2d').drawImage(img, 0, 0, canvas.width, canvas.height);
// 转回Blob
canvas.toBlob(
compressedBlob => resolve(compressedBlob),
'image/jpeg',
quality
);
URL.revokeObjectURL(url); // 释放内存
};
img.src = url;
});
}
三、临时 URL:浏览器中的文件高速公路 🚗💨
// 1. 创建临时访问链接
const createTempUrl = (blob) => {
return URL.createObjectURL(blob);
};
// 2. 应用场景:图片预览
const previewImage = document.getElementById('preview');
const fileInput = document.getElementById('upload');
fileInput.addEventListener('change', (e) => {
const blob = e.target.files[0];
previewImage.src = createTempUrl(blob);
});
// 3. 应用场景:文件下载
function downloadBlob(blob, filename) {
const link = document.createElement('a');
link.href = createTempUrl(blob);
link.download = filename;
document.body.appendChild(link);
link.click();
setTimeout(() => URL.revokeObjectURL(link.href), 100); // 延迟释放
}
四、Blob 实战应用:Excel 文件生成 📊💼
function exportToExcel(data) {
// CSV 内容生成
let csvContent = "名称,价格,库存
";
data.forEach(row => {
csvContent += `${row.name},${row.price},${row.stock}
`;
});
// 转Blob
const blob = new Blob(["\uFEFF" + csvContent], {
type: 'text/csv;charset=utf-8'
});
// 触发下载
downloadBlob(blob, '产品数据.csv');
}
// 使用示例
const products = [
{ name: "手机", price: 3999, stock: 100 },
{ name: "笔记本", price: 8999, stock: 50 }
];
exportToExcel(products);
五、Blob 性能优化与陷阱 🚨
-
内存管理黄金法则 💡
// 创建URL后必须释放! const url = URL.createObjectURL(blob); // 使用完成后立即释放 const release = () => URL.revokeObjectURL(url); // 图片加载后释放 img.onload = release; -
大文件处理技巧 ⚙️
// 使用Streams API处理超大文件 async function processBigFile(blob) { const stream = blob.stream(); const reader = stream.getReader(); while (true) { const { done, value } = await reader.read(); if (done) break; // 处理每个分块 console.log('收到分块:', value.byteLength, 'bytes'); } }
六、Blob 现代应用场景 🌍
-
WebRTC 视频传输 📹
// 录制视频片段 const recorder = new MediaRecorder(stream); const chunks = []; recorder.ondataavailable = e => chunks.push(e.data); recorder.onstop = () => { const videoBlob = new Blob(chunks, { type: 'video/webm' }); // 上传或预览 }; -
PWA 离线文件缓存 📂
// 缓存二进制资源 caches.open('v1').then(cache => { cache.put('/data.zip', new Response(blob)); });
进阶技巧:Blob + Service Worker = 💪
// Service Worker中拦截请求并返回Blob
self.addEventListener('fetch', event => {
if (event.request.url.endsWith('/dynamic-image')) {
event.respondWith(
fetch('/placeholder.jpg')
.then(res => res.blob())
.then(blob => {
// 动态修改图片
return modifyImage(blob);
})
.then(modifiedBlob => {
return new Response(modifiedBlob);
})
);
}
});
Blob 使用三原则:
1️⃣ 用完立即释放内存 (revokeObjectURL)
2️⃣ 大文件使用分片处理
3️⃣ 优先使用 Streams API 替代完整加载
掌握 Blob 对象,你将能在浏览器中完成以前必须依赖服务器的复杂文件操作,真正实现“浏览器即操作系统”的终极理念!🎯
【思考题】如何用 Blob 实现客户端加密文件后再上传?欢迎在评论区分享你的方案!🛠️