浏览器 blob 伪协议:内存里的 “临时 URL”

最近留意到浏览器中有这种链接:blob:https://example.com/28ab6297-2cc6-48e9-8f94-782a620d95da
以前实现过纯前端的文件下载,竟然没有意识到背后的协议,"学无止境"又一次最好的被诠释了。写一篇文章来分享对这个特性的学习。

一、blob: 是什么

  • 定义 :blob是浏览器内存中 Blob/File 对象的临时引用标识符,不是真实网络地址,不会向服务器发起请求。
  • 格式 :blob:origin/唯一UUID,例如 blob:https://example.com:443/28ab...
    • origin 包含协议、域名和端口(端口可省略,省略时使用默认端口)。
    • UUID 由浏览器自动生成,不可手写。
  • 生命周期
    • 仅在当前页面的浏览器中有效,包括手动或通过JS打开的标签页。
    • 原页面刷新/关闭后自动失效,因为内存释放了。
  • API
    • 创建:const url = URL.createObjectURL(blob) 生成 blob URL。
    • 释放:URL.revokeObjectURL(url) 通知浏览器回收内存,避免内存泄漏(尤其在长期运行的单页应用中)。

二、和 Blob 类型的关系

  • Blob :浏览器中的二进制数据容器,可存储图片、视频、文件等原始数据,不可变。
  • blob URL :给 Blob 临时分配一个"内部网址",让 img、video、a 等只能接受 URL 的标签能直接引用内存数据,无需走网络。

三、常见使用场景

1. 图片预览

用户上传本地图片后,生成 blob URL 赋给 img 的 src,实现即时预览。

javascript 复制代码
const img = document.querySelector('img');
// 假设从 <input type="file"> 获取了 File 对象(File 是 Blob 的子类)
const file = fileInput.files[0];
img.src = URL.createObjectURL(file);
2. 前端实现文件下载
javascript 复制代码
const a = document.createElement('a');
const blob = new Blob(['{"name":"test"}'], { type: 'application/json' });
a.href = URL.createObjectURL(blob);
a.download = 'data.json';
document.body.appendChild(a); // 确保元素在 DOM 中(某些安全策略要求)
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(a.href); // 下载后立即释放
3. 视频/音频流式播放

B 站等平台使用 blob URL 播放分段视频,隐藏真实源地址,支持流式加载。

四、使用注意

  • 必须手动释放 :不再使用时调用 revokeObjectURL,否则 Blob 内存会一直被占用(页面关闭后自动释放,但在长期运行的 SPA 中会造成内存泄漏)。
  • 不同页面/标签页无法共享 :blob URL 绑定到创建它的页面上下文,其他标签页无法访问。
  • 不能手写或持久化 :URL 中的 UUID 由浏览器随机生成,无法提前构造,也不能存储下来跨会话使用。