应使用 url.createobjecturl() 获取预览 url,比 filereader.readasdataurl() 更高效;需在更换图片前调用 url.revokeobjecturl() 释放旧引用,避免内存泄漏,并用 css 的 max-width/max-height 和 object-fit 控制显示效果。

input type="file" 选中图片后怎么拿到预览 URL
浏览器不直接暴露本地文件路径,所以不能用 file.value 拼接 file:// 路径。必须用 FileReader 读取二进制内容并转成 Data URL。
关键步骤:监听 input 的 change 事件 → 取出 files[0] → 创建 new FileReader() → 调用 readAsDataURL() → 在 onload 回调里把 reader.result 赋给 <img> 的 src。
- 务必检查
event.target.files.length > 0,否则用户取消选择时files[0]是undefined -
FileReader是异步的,不能在readAsDataURL()后立刻读result - 只支持单图预览?加
multiple属性 + 遍历files数组即可
用 URL.createObjectURL() 还是 FileReader.readAsDataURL()
createObjectURL() 更快、内存更省,适合临时预览;readAsDataURL() 生成 base64 字符串,可存入表单或发给后端,但大图会卡顿、字符串超长还可能触发某些后端限制。
推荐默认用 createObjectURL(),但记得在不需要时手动释放引用,否则内存泄漏:
let currentUrl = null;
input.addEventListener('change', e => {
if (currentUrl) URL.revokeObjectURL(currentUrl);
const file = e.target.files[0];
if (file && file.type.startsWith('image/')) {
currentUrl = URL.createObjectURL(file);
img.src = currentUrl;
}
});
-
createObjectURL()返回的是 blob URL,仅当前页面有效,刷新即失效 - 不调用
revokeObjectURL()会导致浏览器持续持有文件引用,尤其在频繁切换图片时明显 - 如果后续要上传,仍需用
FormData.append('file', file),别传 URL
预览图尺寸变形、模糊、拉伸怎么办
常见原因是直接设 <img style="max-width:90%" style="max-width:90%"> 强制宽高,破坏了原始宽高比。CSS 控制更灵活也更安全。
用 max-width 和 max-height 限制最大尺寸,配合 object-fit: contain 或 cover:
img.preview {
max-width: 300px;
max-height: 200px;
object-fit: contain; /* 保持比例,留白;用 cover 则裁剪 */
background: #f5f5f5;
}
- 不要用内联
width/height属性,它会覆盖 CSS 的max-设置 -
object-fit在 IE 中不支持,如需兼容,得用 JS 计算缩放比 + canvas 绘制 - 移动端注意添加
image-rendering: -webkit-optimize-contrast防止缩放模糊
点击“重选”后预览没清空或报错 Failed to execute 'createObjectURL' on 'URL': No function was found that matched the signature
错误通常是因为传了 null 或已释放的 file 给 createObjectURL(),或者重复调用 revokeObjectURL() 同一个 URL 两次。
稳妥做法:每次选新图前先清理旧引用,并确保只对有效 File 对象调用:
- 把
currentUrl存在闭包或data-属性里,避免变量污染 - 在
change回调开头就执行if (currentUrl) URL.revokeObjectURL(currentUrl) - 清空预览图时,设
img.src = '',再置空currentUrl,别留僵尸引用 - 如果用了
multiple,还要注意遍历撤销多个 URL
真正麻烦的不是读图,而是管好这些临时 URL 的生命周期 —— 忘了 revoke,页面开久了内存就悄悄涨上去了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











