createObjectURL生成的链接是浏览器内存中的临时引用,非持久化存储,页面刷新或调用revokeObjectURL后即失效;不可用于大文件中转缓存或服务端暂存,应改用分块+IndexedDB或FileSystem API。

createObjectURL 生成的链接本质是内存引用,不是文件存储
它只是浏览器内部为 Blob 或 File 对象创建的一个临时、唯一的 URL 字符串(形如 blob:https://example.com/abc123),背后不写磁盘,也不持久化。一旦页面刷新、标签页关闭,或显式调用 URL.revokeObjectURL(),该链接立即失效,对应数据可能被 GC 回收。
大文件上传时别依赖 createObjectURL 做“中转缓存”
用户选中一个 500MB 的视频文件,URL.createObjectURL(file) 确实能快速生成可预览的链接,但此时整个文件内容已加载进内存(或由浏览器底层映射管理)。对内存压力大,且无法控制生命周期——比如用户切到别的标签页再回来,链接大概率已失效。
- 不要用它替代后端上传:它不能帮你把文件“暂存”到服务端,只是前端本地的一次性视图代理
- 不要长期保存该 URL 字符串:它不跨会话,
localStorage存了也没用 - 避免多个大文件连续调用不 revoke:容易触发内存警告甚至页面崩溃
真正需要“临时存储大文件”的可行路径
如果目标是让用户上传后能暂停、续传、或离线稍后提交,createObjectURL 不是解法,应转向分块 + IndexedDB 或 FileSystem API(仅 Chromium):
- 用
File.slice()拆分大文件,每块转成Blob后存入indexedDB(需封装为二进制对象存储) - Chrome/Edge 可尝试
window.showDirectoryPicker()配合FileSystemFileHandle.createWritable(),直接操作沙盒目录(需用户授权) - 若必须用 URL 预览,只在需要时生成,并在不用时立刻
URL.revokeObjectURL(url)—— 尤其在src属性卸载或组件销毁时
例如:
let blobUrl = null;
function preview(file) {
if (blobUrl) URL.revokeObjectURL(blobUrl);
blobUrl = URL.createObjectURL(file);
video.src = blobUrl;
}
// 组件 unmount 或用户取消上传时:
if (blobUrl) {
URL.revokeObjectURL(blobUrl);
blobUrl = null;
}
移动端和 Safari 的兼容性陷阱
iOS Safari 对 createObjectURL 返回的 blob URL 支持有限:无法用于 <video> 的 src(会静音或报错 NotAllowedError),也不能通过 fetch() 读取。Android WebView 表现也参差不齐。
- 不要假设
fetch(blobUrl)在所有环境都能成功读回原始字节 - 移动端预览大视频,优先考虑
fileReader.readAsArrayBuffer()+MediaSource流式加载,而非全量生成 blob URL - 检查
URL.createObjectURL是否存在且返回值非空,Safari 15.4 之前某些场景会静默失败
createObjectURL 是个快捷预览工具,不是缓存机制。真要落地,得绕开它,直奔 IndexedDB 或原生文件系统。

















