核心是用filereader读取本地文件生成data url预览,而非拼接file://路径;需监听change事件、校验files[0]有效性、处理多文件及兼容性问题,并注意内存泄漏和exif朝向修正。

用 <input type="file"> 选图后如何立刻显示预览
核心就一条:别发请求,用 FileReader 读取本地文件的 data URL。浏览器禁止直接用 file:// 路径渲染图片(出于安全限制),所以不能把 input.files[0].path 拼成 src —— 那会失败,且 .path 在大多数浏览器里根本是空字符串或不可访问的。
实操要点:
- 监听
input的change事件,而不是click或blur - 检查
input.files.length > 0,再取input.files[0],避免报错 - 只支持图片类型?加个
accept="image/*"属性,但注意它只是提示,不阻止用户手动选其他文件 - 创建
new FileReader(),调用readAsDataURL(file),在onload里把reader.result赋给<img>.src
FileReader 报错 “Failed to execute 'readAsDataURL' on 'FileReader'” 怎么办
常见于传了非 File 对象进去,比如误传了 input.value(字符串)或 input.files(FileList 对象,不是单个 File)。
排查步骤:
- 打印
console.log(input.files[0], input.files[0] instanceof File),确认是File实例 - 确保没在
input上设multiple却没处理多文件逻辑(例如直接取[0]但用户没选任何文件) - 某些旧版 Safari 对
data:image/xxx;base64,...的 URL 长度有限制,超长图可能加载失败,可降级用createObjectURL()(但记得后续revokeObjectURL)
要不要用 URL.createObjectURL() 替代 FileReader
可以,而且更轻量——它不读取文件内容,只生成一个指向本地文件的临时内存 URL。适合大图或快速预览场景。
但要注意:
-
createObjectURL()返回的 URL 是临时的,页面刷新即失效;FileReader的 data URL 是纯文本,可存、可传、可复用 - 必须手动清理:在不需要时调用
URL.revokeObjectURL(url),否则内存泄漏(尤其反复选图) - 部分安卓 WebView 或老版 UC 浏览器对
createObjectURL支持不稳定,FileReader兼容性更好(IE10+) - 示例写法:
img.src = URL.createObjectURL(file);,之后在换图或卸载前执行URL.revokeObjectURL(img.src)
上传前压缩图片再预览,会影响预览效果吗
不影响预览本身,但会改变你看到的图——压缩是异步操作,必须等压缩完成才能设置 img.src。如果跳过压缩直接预览,用户看到的是原图;如果压缩后再预览,看到的就是压缩后的版本。
关键点:
- 压缩逻辑(如用
canvas绘制缩放)必须在FileReader.onload之后触发,因为需要先拿到原始图像数据 - 不要在压缩过程中直接改原
<img>的src,否则可能中断 canvas 绘制 - 压缩后生成的
Blob可用URL.createObjectURL()预览,也可转成 base64 再赋值(但大图慎用 base64,内存压力大) - 移动端 iOS Safari 对 canvas 压缩后的 EXIF 朝向处理不一致,预览图可能旋转错位,需额外解析 EXIF 修正
objectURL 或未重置 img.src 导致残留、卡顿甚至内存溢出。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











