一文了解 Blob 文件格式:前端必备技能之一
(2026年最新 MDN + 实战总结版,适合初级到中高级前端)
在现代前端开发中,Blob 是处理二进制数据的核心对象,几乎所有涉及文件、图片、视频、下载、上传、剪裁、流媒体的场景都离不开它。
很多人把 Blob 当成“神秘的黑盒”,其实它非常简单:Blob = 不可变的原始二进制数据块 + MIME 类型 + 大小信息。
一、Blob 是什么?一句话定义
Blob(Binary Large Object,二进制大对象)是一个不可变的、类文件的原始数据对象。它可以表示任意二进制内容(如图片、PDF、Excel、视频、甚至纯文本),数据可以按文本或二进制方式读取,还能转成 ReadableStream 处理。
关键特性(背下来就够了):
- 不可变(immutable):创建后内容不能修改(想改只能 slice 或新建)
- 类文件:像文件一样有
size和type,但不一定来自文件系统 - 不依赖 JavaScript 原生格式:可以是任意字节序列
- File 是 Blob 的子类:File 继承 Blob,多了
name、lastModified等文件元信息
二、Blob vs File vs ArrayBuffer 对比表(面试必备)
| 特性 | Blob | File (继承自 Blob) | ArrayBuffer |
|---|---|---|---|
| 是否不可变 | 是 | 是 | 是(但 TypedArray 可视图修改) |
| 是否有文件名 | 否 | 是(name 属性) | 否 |
| 是否有最后修改时间 | 否 | 是(lastModified) | 否 |
| MIME 类型 | 有(type,可手动指定) | 有(继承 + 自动推断) | 无 |
| 主要用途 | 二进制存储、下载、上传、流处理 | 用户选择的文件、拖拽文件 | 底层二进制缓冲区、操作字节 |
| 能否直接 slice | 是 | 是 | 否(需用 TypedArray 或 DataView) |
| 能否直接创建 URL | 是(URL.createObjectURL) | 是 | 否(需转 Blob) |
| 内存占用 | 引用底层数据,不复制 | 同 Blob | 固定缓冲区 |
三、Blob 的创建方式(最常用 5 种)
- 从数组创建(最基础)
const blob = new Blob(["Hello 重阳!"], { type: "text/plain" });
// 或混合类型
const mixed = new Blob([
"<h1>标题</h1>",
new Uint8Array([0x68, 0x65, 0x6C, 0x6C, 0x6F]),
new Blob(["世界"])
], { type: "text/html" });
- 从文件输入创建(input type=”file”)
<input type="file" id="fileInput">
<script>
fileInput.onchange = e => {
const file = e.target.files[0]; // 这就是一个 File 对象(继承 Blob)
console.log(file instanceof Blob); // true
console.log(file.type); // 如 image/png
};
</script>
- 从 fetch / axios 下载创建(最常见下载场景)
async function downloadExcel() {
const res = await fetch('/api/export');
const blob = await res.blob(); // 直接得到 Blob
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = '报表.xlsx'; // 指定文件名
a.click();
URL.revokeObjectURL(url); // 释放内存(重要!)
}
- 从 canvas / 视频截图创建
canvas.toBlob(blob => {
// blob 就是 image/png 的 Blob
// 可以上传、下载、预览
}, 'image/png', 0.95);
- 从 ArrayBuffer / TypedArray 创建
const buffer = new ArrayBuffer(1024);
const view = new Uint8Array(buffer);
view[0] = 0xFF;
const blob = new Blob([view], { type: 'application/octet-stream' });
四、Blob 的核心方法 & 属性(日常必用)
| 属性/方法 | 作用 | 返回类型 | 使用频率 |
|---|---|---|---|
size | 数据字节长度 | number | ★★★★★ |
type | MIME 类型(如 “image/jpeg”) | string | ★★★★★ |
slice(start, end, type) | 裁剪子 Blob(支持负索引) | Blob | ★★★★☆ |
text() | 读取为 UTF-8 文本 | Promise | ★★★★☆ |
arrayBuffer() | 读取为 ArrayBuffer | Promise | ★★★★☆ |
stream() | 转为 ReadableStream(流式处理大文件) | ReadableStream | ★★★☆☆ |
大文件分片上传经典写法:
async function uploadLargeFile(file) {
const chunkSize = 5 * 1024 * 1024; // 5MB
const chunks = [];
for (let start = 0; start < file.size; start += chunkSize) {
const chunk = file.slice(start, start + chunkSize);
chunks.push(chunk);
// await uploadChunk(chunk, index);
}
}
五、Blob 的经典使用场景(生产必备)
- 文件下载(后端返回二进制流)
- 图片/文件预览(URL.createObjectURL(blob) → img.src)
- 大文件分片上传(slice + FormData)
- canvas / video 导出(toBlob / captureStream)
- 剪贴板图片处理(Clipboard API 返回 Blob)
- SSE / WebSocket 二进制传输(结合 stream())
- PDF/Excel 生成(如 pdfmake、xlsx 库输出 Blob)
六、常见坑 & 最佳实践(2026 年提醒)
- 内存泄漏:用完
URL.createObjectURL后一定要URL.revokeObjectURL(url),否则 Blob 无法被 GC - type 不指定 → 默认空字符串,下载时浏览器可能无法识别文件类型
- 跨域问题:fetch 时加
response.blob()前确保 CORS 支持 - 大文件:优先用
stream()+ pipeTo,避免一次性读入内存 - FileReader 已过时:现代代码优先用
blob.text()/blob.arrayBuffer()/blob.stream()
一句话总结:
Blob 是前端处理“一切非结构化二进制数据”的统一入口。掌握 Blob + URL.createObjectURL + fetch.blob() + slice,你就打通了文件上传、下载、预览、导出、分片等 80% 的文件相关需求。
你现在最常在哪个场景用到 Blob?
(文件下载卡顿?大文件上传失败?图片预览内存爆?canvas 导出?)
告诉我具体需求,我可以给你针对性的完整代码模板~