input.files是获取图片文件的唯一合法入口,需监听change事件,用filereader.readasdataurl()生成data url预览,注意空文件、类型校验、内存释放及错误提示。

input[type="file"] 选中后怎么拿到图片文件
浏览器不会直接暴露本地路径,input.files 是唯一合法入口。它返回 FileList,每个项是 File 实例(继承自 Blob),可直接用于 URL.createObjectURL() 或 FileReader。
常见错误:试图读取 input.value 获取路径——现代浏览器返回假路径(如 C:\fakepath\xxx.jpg),且无法用于读取文件内容。
- 必须监听
input的change事件,而非click -
input.files[0]才是用户选中的第一个文件;多选需遍历input.files - 检查
input.files.length === 0防止误操作(比如取消选择后触发)
用 FileReader 读取图片并显示缩略图
FileReader 是最兼容的方案,支持所有现代浏览器,且不依赖服务器。它把 File 转成 data: URL,可直接赋给 <img src>。
注意:不能用 fetch() 或 XMLHttpRequest 直接读取 File 对象,它们只接受 URL 或 Blob(但需构造 URL.createObjectURL() 后才能作为 URL 使用)。
- 优先用
reader.readAsDataURL(file),生成 base64 字符串,适合小图预览 - 避免用
readAsArrayBuffer()或readAsText()——对图片无意义 - 记得在
reader.onload中设置img.src = reader.result,别漏掉.result - 加载失败时监听
reader.onerror,例如用户选了非图片文件
const input = document.querySelector('input[type="file"]');
input.addEventListener('change', (e) => {
const file = e.target.files[0];
if (!file || !file.type.startsWith('image/')) return;
const reader = new FileReader();
reader.onload = () => {
const img = document.querySelector('#preview');
img.src = reader.result; // reader.result 是 data: URL
};
reader.onerror = () => console.error('读取失败');
reader.readAsDataURL(file);
});
限制缩略图尺寸和内存泄漏风险
直接使用 createObjectURL() 或 readAsDataURL() 生成的 URL 会常驻内存,尤其大图反复上传时容易撑爆内存。
缩略图本身不需要原始分辨率——用户只是看个样子,没必要加载 5MB 的 PNG 做预览。
- 用
URL.createObjectURL(file)更轻量,但必须手动调用URL.revokeObjectURL()释放 - 若用
readAsDataURL(),base64 字符串会随 DOM 存在,无需显式释放,但字符串体积是原图 1.33 倍 - 真正控制尺寸:在
<img>上设width/heightCSS,或用object-fit: cover防止拉伸 - 更进一步可 Canvas 绘制缩放图再转
toDataURL(),但仅当需统一尺寸/压缩质量时才值得做
处理不支持的文件类型或空选择
用户可能点“选择文件”后直接点取消,也可能拖入 PDF、视频等非图文件——此时 input.files 为空或 file.type 不匹配,FileReader 会静默失败或报错。
不要依赖 MIME 类型 100% 准确(比如 .jpg 文件可能被识别为 application/octet-stream),可结合扩展名简单兜底。
- 先检查
if (!file) return,避免后续报Cannot read property 'type' of undefined - 用
file.name.split('.').pop().toLowerCase()辅助判断扩展名(如['jpg','jpeg','png','gif','webp']) - 预览区域清空逻辑要明确:
img.src = ''或img.removeAttribute('src'),否则旧图残留 - 错误提示建议写在 UI 层(如
<div class="error">仅支持图片格式</div>),别只打 console
URL.revokeObjectURL() 的调用时机,以及未拦截空文件导致后续逻辑崩掉。缩略图这事看着简单,卡在细节上反而比写个 API 请求还费时间。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











