大家好,很高兴又见面了,我是”高级前端进阶”,由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发,您的支持是我不断创作的动力。
1. 什么是 Blob URL
在 Web 开发中,常常会遇到需要直接在浏览器中处理数据而不通过服务器。此时,Blob URL 就派上用场了。其是一种强劲的客户端数据处理机制,能够提供灵活性和性能优势。
那么,Blob URL 究竟是什么呢?

其表明以二进制大对象(BLOB)形式存储在浏览器中的数据,开发者也可以将其看做是存储在浏览器内存中的文件,Blob URL 本质上是指向该文件的临时链接。开发者也可以将其视为指向原始数据的指针,无论是图像、视频、音频还是任何其他类型的文件,这类 URL 都以 blob: 开头。
Blob URL 具有以下几个显著优势:
- 直接通过客户端数据处理:允许开发者直接在浏览器中处理数据而无需将其上传到服务器,在文件预览、动态内容创建(例如:从 Canvas 创建图片)、离线处理等场景超级有用
- 性能提升:通过避免不必要的服务器往返,Blob URL 可以显著提升 Web 应用程序的性能。开发者无需与服务器来回发送数据,而是直接在本地操作
- 降低服务器负载:将数据处理转移到客户端可以大大减轻服务器负载,提高应用程序的可扩展性
- 增强用户体验:即时预览和离线访问等功能可带来更流畅、响应更快的用户体验
同时,值得一提的是,Blob URL 还具有以下特性:
- 临时性:Blob URL 是临时的,其仅在创建的页面处于打开状态时存在。如果用户关闭或刷新页面,Blob URL 会自动失效
- 作用域:Blob URL 只能在创建的浏览器上下文中访问,不能在不同的浏览器标签页或网站之间共享
- 内存管理:由于 Blob URL 表明存储在内存中的数据,因此谨慎管理至关重大。使用完 Blob URL 后,应使用 URL.revokeObjectURL() 释放关联的内存,从而防止内存泄漏
document.getElementById("downloadBtn").addEventListener("click", () => {
// 创建一个 Blob 对象(模拟文件内容)
const content = "这是一个由 Blob 生成的文本文件内容";
const blob = new Blob([content], { type: "text/plain" });
// 创建一个对象 URL
const objectURL = URL.createObjectURL(blob);
// 创建 <a> 元素用于下载
const a = document.createElement("a");
a.href = objectURL;
a.download = "example.txt";
// 指定下载文件名
document.body.appendChild(a);
a.click();
// 下载完成后释放内存
a.addEventListener("click", () => {
document.body.removeChild(a);
URL.revokeObjectURL(objectURL); // 释放对象 URL
console.log("对象 URL 已释放");
});
});
2.Blob URL 是如何工作的
创建 Blob 时,浏览器会自动获取开发者提供的数据,例如:可能来自文件上传、Canvas 元素或 API 响应的数据等,并将其存储在内存中。然后,浏览器会生成一个指向该数据的唯一 URL,该 URL 就是 Blob URL。
2.1 使用文件输入创建 Blob URL
下面示例使用文件输入创建 Blob URL:
const fileInput = document.getElementById("imageInput");
fileInput.addEventListener("change", (event) => {
const file = event.target.files[0];
// 获取选中的文件
if (file) {
const blob = new Blob([file], { type: file.type });
// 创建 Blob
const blobUrl = URL.createObjectURL(blob);
// 创建 Blob URL 对象
const imgElement = document.getElementById("imagePreview");
imgElement.src = blobUrl;
// 使用 blob 或者 blobUrl 实现业务逻辑
}
});
2.2 使用 Uint8Array 二进制数据创建 Blob URL
开发者还可以使用 Uint8Array 格式的图像数据,例如:fetch 请求或 WebSocket 返回的数据,来创建 Blob:
fetch("image.jpg")
.then((response) => response.arrayBuffer())
.then((buffer) => {
const uint8Array = new Uint8Array(buffer);
const blob = new Blob([uint8Array], { type: "image/jpeg" });
// 注意:要选中正确的类型
const blobUrl = URL.createObjectURL(blob);
const imgElement = document.getElementById("imagePreview");
imgElement.src = blobUrl;
// 使用 blob 或者 blobUrl 创建业务逻辑
});
此时,开发者可以像使用其他 URL 一样使用此 Blob URL,例如:可以将其设置为 <img> 标签的 src 来显示图像或使用其来下载数据。
3. 使用 Blob URL 创建 Worker
开发者在创建 Worker 时常常会遇到下面的错误:
Uncaught (in promise) DOMEXception: Failed to construct 'Worker' (…) cannot be accessed from origin (…)
这是由于 Worker 脚本的创建必须遵循同源策略,即与主页面同源。此时,Blob URL 就派上用场了。下面示例使用 Blob URL 来动态创建 Worker,从而有效绕过同源策略:
const type = "application/javascript";
export default (originalWorkerUrl, _options = {}) => {
const options = {
skipSameOrigin: true,
useBlob: true,
..._options,
};
if (
!originalWorkerUrl.includes("://") ||
originalWorkerUrl.includes(window.location.origin)
) {
// 如果同源,直接 resolve 返回
return Promise.resolve(originalWorkerUrl);
}
// 如果不同源则获取内容再创建 worker
return new Promise((resolve, reject) =>
fetch(originalWorkerUrl)
.then((res) => res.text())
.then((codeString) => {
let workerPath = new URL(originalWorkerUrl).href.split("/");
workerPath.pop();
// 删除最后一级路径,例如:https://developer.mozilla.org/en-US/docs/Web
// workerPath 将包含路径 https://developer.mozilla.org/en-US/docs
const importScriptsFix = `const _importScripts = importScripts;
const _fixImports = (url) => new URL(url, '${
workerPath.join("/") + "/"
}').href;
importScripts = (...urls) => _importScripts(...urls.map(_fixImports));`;
// 1.new URL 的第二个参数是 base 路径
// 如果 url 是绝对 URL,则不会使用给定的 base 路径来创建结果 URL
// 2.new URL("umd/comlink.js", 'https://somedoamin.com/public/').href;
// 输出结果为 https://somedoamin.com/public/umd/comlink.js
let finalURL =
`data:${type},` + encodeURIComponent(importScriptsFix + codeString);
// data URL(以 data: 格式为前缀的 URL)允许内容创建者在文档中
// 内联嵌入小文件
if (options.useBlob) {
finalURL = URL.createObjectURL(
new Blob([`importScripts("${finalURL}")`], { type })
);
}
// 创建 Blob URL 对象
resolve(finalURL);
})
.catch(reject)
);
};
该方法的本质是通过自动获取 URL 脚本的内容,同时创建一个 URL Blob 作为新的 URL 地址完成,下面是使用该方法的示例:
import getCrossOriginWorkerURL from "crossoriginworker";
async function createWorker() {
const workerURL = await getCrossOriginWorkerURL(
"https://somedomain.com/lib/awesome.worker.js"
);
return new Worker(workerURL);
}
const myWorker = await createWorker();
参考资料
https://dev.to/harsh8088/blob-urls-explained-how-they-work-and-why-they-matter-302d
https://github.com/CezaryDanielNowak/CrossOriginWorker
https://developer.mozilla.org/en-US/docs/Web/API/URL/URL
https://developer.mozilla.org/en-US/docs/Web/URI/Reference/Schemes/data



掌握了创建Blob URL方法
收藏了,感谢分享