必须监听 choose 回调而非 done,在 obj.files 中获取 File 对象并用 URL.createObjectURL 生成临时预览 URL,同时注意手动 revoke 避免内存泄漏。

layui upload 上传前用 URL.createObjectURL 预览图片
layui 的 upload 组件本身不内置上传前预览逻辑,得靠手动监听 choose 回调,在文件选中后读取 files 列表并生成临时 URL。关键不是等上传完成,而是趁浏览器还持有原始 File 对象时立刻处理。
常见错误是直接在 done 回调里尝试读取服务端返回的图片地址——此时文件还没传完,或者服务端还没返回可访问链接,用户已经想看效果了。
- 必须监听
choose而非done或before -
choose回调参数obj的obj.files是原生FileList,可直接取[0](单图)或遍历(多图) - 用
URL.createObjectURL(file)生成仅当前页面有效的 blob URL,赋给<img>的src - 记得在下次选择或重置时调用
URL.revokeObjectURL避免内存泄漏
单图上传 + 实时预览的最小可行代码
以下是在 upload.render() 中启用预览的典型写法,适用于 layui 2.8+:
layui.use('upload', function(){
var upload = layui.upload;
upload.render({
elem: '#uploadBtn',
url: '/api/upload',
auto: false, // 关键:关闭自动上传,留给 choose 处理预览
choose: function(obj){
var file = obj.files[0];
if (!file || !file.type.match('image.*')) return;
var img = document.getElementById('previewImg');
img.src = URL.createObjectURL(file);
// 绑定上传动作到按钮或自动触发
obj.preview(function(index, file, result){
// 可选:上传成功后替换为真实地址
});
}
});
});
注意:obj.preview 是 layui 2.7+ 提供的辅助方法,它内部已做 revoke 清理;如果不用它,就得自己记下 URL 并在后续手动释放。
前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。
立即学习“前端免费学习笔记(深入)”;
多图预览要注意 DOM 更新和内存管理
多图场景下,obj.files 是多个 File,不能只取第一个。同时要避免反复 createObjectURL 不释放导致内存堆积。
- 每次
choose前先清理旧的预览容器(如清空<div id="previewBox">内容) - 对每个
file单独调用URL.createObjectURL,生成独立<img> - 若用户重复选择同一组文件,浏览器可能复用
File对象,但 URL 仍需新生成——不要缓存createObjectURL结果 - layui 没有提供多图的批量
preview方法,得自己循环处理
为什么不用 FileReader.readAsDataURL?
虽然也能实现预览,但 readAsDataURL 会把整个文件读成 base64 字符串,大图(比如 5MB JPG)会导致内存飙升、主线程卡顿,且 base64 字符串体积比原始二进制大 33%。而 URL.createObjectURL 只是创建引用,不拷贝数据,性能好得多。
真正容易被忽略的是:预览只是前端行为,和上传是否成功无关;很多开发者卡在“预览不出来”,其实是因为没关 auto: true,导致 choose 后立刻发请求,files 在回调里已被清空或不可读。

















