URL.createObjectURL 是临时预览首选方案,因其生成同源 blob URL,可直接用于媒体标签且无需服务端;需配对 revokeObjectURL 防内存泄漏,并注意类型校验、事件监听及跨浏览器兼容性。

为什么 URL.createObjectURL 是临时预览的首选方案
因为浏览器不支持直接用 file:// 路径加载本地文件(尤其在现代 Chrome/Firefox 中会触发 CORS 或空白页),而 URL.createObjectURL 生成的是内存内、同源、可直接用于 <img>、<video>、<audio> 的 blob URL,无需服务端介入。
注意:它不是“上传”,也不是“转 base64”,而是创建一个指向内存中 Blob 的引用地址 —— 快、轻量、无编码开销。
怎么给 <input type="file"> 选中的图片生成预览
监听 change 事件后,取 event.target.files[0] 创建 URL,并赋值给 <img src>:
const input = document.querySelector('input[type="file"]');
const img = document.querySelector('#preview');
input.addEventListener('change', (e) => {
const file = e.target.files[0];
if (!file) return;
// 清掉旧的 URL(避免内存泄漏)
if (img.src) URL.revokeObjectURL(img.src);
img.src = URL.createObjectURL(file);
});
- 必须检查
files[0]是否存在,空选择时files是空列表 - 每次调用
createObjectURL都要配对revokeObjectURL,否则 Blob 一直驻留内存 -
img.src赋值后浏览器自动触发加载,不需要手动img.load()
预览视频或音频时要注意什么
<video> 和 <audio> 同样适用,但需注意资源类型校验和播放控制:
立即学习“前端免费学习笔记(深入)”;
- 用
file.type判断是否为支持的 MIME 类型(如"video/mp4"、"audio/mpeg"),避免无效 URL 导致静音或黑屏 - 设置
controls属性才能显示播放控件;若想自动播放,需加muted(尤其video) - 不要在
src改变后立即调用play(),应监听loadedmetadata事件再触发
示例片段:
video.src = URL.createObjectURL(file);
video.addEventListener('loadedmetadata', () => video.play(), { once: true });
常见报错和陷阱
最常遇到的是 DOMException: Failed to execute 'createObjectURL' on 'URL': No function was found that matched the signature provided. —— 这说明传入了非 Blob 或 File 实例。
-
fetch().then(res => res.blob())返回的是Blob,可用;但res.text()或res.json()不行 - 别把
ArrayBuffer直接传进去,得先new Blob([arrayBuffer], {type: '...'}) - React/Vue 等框架中,若在组件卸载后仍尝试
revokeObjectURL,会报 “URL not found” 错误,需加判断或清理副作用 -
createObjectURL在 Safari 上对某些大视频文件可能延迟明显,建议加 loading 状态提示
临时预览的本质是“内存引用”,不是持久化。页面刷新或关闭标签页后 URL 失效,这点必须心里有数。



















