Blob(Binary Large Object,二进制大对象)是浏览器提供的一种
不可变、类文件的原始数据容器。它可以存储任意类型的二进制或文本数据,例如图片、音频、PDF、甚至一段纯文本。与
File 对象相比,Blob 更底层,File 实际上继承自 Blob,并额外携带了
name、
lastModified 等元信息 。
Blob 最大的特点是 纯客户端、零网络:数据一旦进入 Blob,就活在内存里,无需上传服务器即可预览、下载或进一步加工。
const blob =
new
Blob(parts, options);
| 参数 | 说明 |
|---|---|
parts |
数组,元素可以是
String、
ArrayBuffer、
TypedArray、
Blob 等。 |
options |
可选对象,常用字段:
type MIME 类型,默认
application/octet-stream;
endings 是否转换换行符,几乎不用。 |
示例:动态生成一个 Markdown 文件并让用户下载
const content =
'# Hello Blob\n> 由浏览器动态生成';
const blob =
new
Blob([content], {
type:
'text/markdown' });
const url =
URL.
createObjectURL(blob);
const a =
document.
createElement(
'a');
a.
href = url;
a.
download =
'hello.md';
a.
click();
// 内存用完即弃
URL.
revokeObjectURL(url);
const url =
URL.
createObjectURL(blob);
// 返回值样例
// blob:https://localhost:3000/550e8400-e29b-41d4-a716-446655440000
close()、手动调用
revokeObjectURL() 都会使其失效 。最佳实践封装:
function
createTempURL(
blob) {
const url =
URL.
createObjectURL(blob);
// 自动 revoke,避免忘记
requestIdleCallback(
() =>
URL.
revokeObjectURL(url));
return url;
}
| 场景 | 推荐格式 | 理由 |
|---|---|---|
图片回显、
<img>/
<video> |
Blob URL | 浏览器可直接解析,无需解码;内存占用低。 |
| 小图标内嵌在 CSS/JSON | Base64 | 减少一次 HTTP 请求,但体积增大约 33%。 |
| 纯计算、WebAssembly 传递 | ArrayBuffer | 可写、可索引,适合高效运算。 |
| 上传大文件、断点续传 | Blob.slice | 流式分片,配合
File.prototype.slice 做断点续传 。 |
<
input
type=
"file"
accept=
"image/*"
id=
"uploader">
<
img
id=
"preview"
style=
"max-width: 100%">
<
script>
uploader.
onchange =
e => {
const file = e.
target.
files[
0];
if (!file)
return;
const url =
URL.
createObjectURL(file);
preview.
src = url;
preview.
onload =
() =>
URL.
revokeObjectURL(url);
// 加载完即释放
};
</
script>
canvas.
toBlob(
blob => {
const url =
URL.
createObjectURL(blob);
const a =
document.
createElement(
'a');
a.
href = url;
a.
download =
'snapshot.png';
a.
click();
URL.
revokeObjectURL(url);
},
'image/png');
fetch(
'https://i.imgur.com/xxx.png', {
mode:
'cors' })
.
then(
r => r.
blob())
.
then(
blob => {
const url =
URL.
createObjectURL(blob);
document.
querySelector(
'img').
src = url;
});
若出现
图片不显示,99% 是因为服务端未返回
Access-Control-Allow-Origin 头 。
<""><""><""><"">
<"www.hat.olbzhibo.com"><""><""><"www.kite.olbzhibo.com">
| 坑点 | 解决方案 |
|---|---|
| 内存暴涨 | 每次
createObjectURL 后,务必在合适的时机
revokeObjectURL 。 |
| 跨域失败 | 确认服务端开启 CORS;fetch 时加
{credentials: 'include'} 如需 Cookie。 |
| 移动端大视频卡顿 | 避免一次性读完整文件,使用
blob.slice(start, end) 分段读取。 |
| 旧浏览器兼容 | IE10+ 才原生支持 Blob;如需更低版本,请引入 Blob.js 兼容库。 |
当文件超大(GB 级)时,全部读进内存并不现实。可以借助
ReadableStream 把 Blob 转为流,实现渐进式上传:
const stream = blob.
stream();
// 返回 ReadableStream
await
fetch(
'/upload', {
method:
'POST',
body: stream,
headers: {
'Content-Type': blob.
type }
});
Chrome 85+、Edge 85+、Firefox 已经支持
blob.stream(),能以
流式形式边读边传,内存占用极低。
用好 Blob,既能 提升用户体验(秒开预览),又能 降低服务端压力(无需中转),是每一位前端工程师的必备技能。
<""><""><"www.nest.olbzhibo.com"><"">
<""><"www.rat.olbzhibo.com"><""><"www.top.olbzhibo.com">
<""><""><""><"www.knot.olbzhibo.com">
<""><""><""><"">
<"www.pant.olbzhibo.com"><"www.quit.olbzhibo.com"><""><"">
<"www.tent.olbzhibo.com"><"www.tree.olbzhibo.com"><"www.uxxt.olbzhibo.com"><"">
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/53956/viewspace-3105440/ ,如需转载,请注明出处,否则将追究法律责任。