在前端开发中,掌握 Blob
和 File
对象的使用至关重要,它们是处理文件上传、下载、预览等操作的核心工具。以下是对这两个对象的深入解析及其在实际开发中的应用示例。
📦 Blob
与 File
的关系
- Blob(Binary Large Object):表示不可变的原始数据,通常用于处理二进制数据,如图像、音频等。
- File:继承自
Blob
,并添加了文件名(name
)和最后修改时间(lastModified
)等属性,专门用于表示用户系统上的文件。([知乎专栏][1], [开源中国][2])
简而言之,File
是一个带有元数据的 Blob
,更适合用于文件上传等场景。
🔧 常见操作示例
1. 实时预览用户上传的头像
通过 FileReader
将用户上传的图片文件读取为 Data URL,实现即时预览:([掘金][3])
<input type="file" id="avatar" accept="image/*">
<img id="preview" alt="头像预览">
document.getElementById('avatar').addEventListener('change', function(e) {
const file = e.target.files[0];
const reader = new FileReader();
reader.onload = function(event) {
document.getElementById('preview').src = event.target.result;
};
reader.readAsDataURL(file);
});
2. 大文件分片上传
使用 Blob.prototype.slice
方法将大文件分割成小块,逐个上传,支持断点续传:([javascript.ruanyifeng.com][4])
function uploadFileInChunks(file) {
const CHUNK_SIZE = 1024 * 1024; // 1MB
let start = 0;
while (start < file.size) {
const end = Math.min(start + CHUNK_SIZE, file.size);
const chunk = file.slice(start, end);
// 发送 chunk 到服务器
start = end;
}
}
3. 浏览器端生成并下载文件
创建一个 Blob
对象,并通过 URL.createObjectURL
生成下载链接:
const content = 'Hello, world!';
const blob = new Blob([content], { type: 'text/plain' });
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = 'hello.txt';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
4. 图片压缩处理
利用 canvas
对上传的图片进行压缩,减少文件大小:
function compressImage(file, quality = 0.8) {
return new Promise((resolve) => {
const reader = new FileReader();
reader.onload = function(event) {
const img = new Image();
img.onload = function() {
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
canvas.getContext('2d').drawImage(img, 0, 0);
canvas.toBlob(resolve, 'image/jpeg', quality);
};
img.src = event.target.result;
};
reader.readAsDataURL(file);
});
}
5. 文件与二进制数据的互相转换
- File → ArrayBuffer:
file.arrayBuffer().then(buffer => {
// 处理 ArrayBuffer 数据
});
- Blob → Base64:
const reader = new FileReader();
reader.onload = function(event) {
const base64 = event.target.result;
// 使用 base64 数据
};
reader.readAsDataURL(blob);
- Base64 → Blob:
fetch(base64Data)
.then(res => res.blob())
.then(blob => {
// 使用 blob 数据
});
⚠️ 注意事项
- 内存管理:使用
URL.createObjectURL
创建的 URL 在不再需要时应调用URL.revokeObjectURL
释放资源。 - 文件类型验证:不要完全依赖
file.type
,应读取文件内容进行验证,以防止伪造。 - 大文件处理:对于大文件,优先使用
stream()
方法处理,避免内存占用过高。 - 浏览器兼容性:某些浏览器(如 Safari)对
Blob
的支持可能存在差异,需进行兼容性测试。([MDN Web Docs][5])
通过熟练掌握 Blob
和 File
的使用,可以大大提升前端在文件处理方面的能力,实现更丰富的功能和更好的用户体验。