HTML文件上传后需监听input的change事件,用e.target.files获取FileList并渲染文件名、大小、类型图标;用外部数组累积文件并去重,每次提交前清空input.value防止重复触发,列表增删须双向同步数据与视图。

HTML 文件上传后如何实时显示文件名列表
原生 本身不提供文件列表展示能力,必须手动读取 input.files 并渲染 DOM。关键在于监听 change 事件,而非 click 或 input(后者在多选取消时不可靠)。
常见错误是直接遍历 e.target.value——它只返回最后一个文件路径(且被浏览器脱敏),完全无法获取多文件信息或真实文件名。
- 用
e.target.files获取FileList对象,它是只读类数组,支持.length和索引访问 - 每个
File对象有.name、.size、.type属性,足够构建基础列表 - 避免用
innerHTML += ...动态拼接,会触发重复解析和事件丢失;推荐清空后用document.createElement批量插入
多文件上传时如何防止重复添加和列表错乱
用户可能多次点击上传按钮并选择文件,若不做控制,files 会覆盖而非追加——浏览器原生行为就是“替换”,不是“累加”。所以不能依赖 input 自身维护状态。
实际做法是用一个外部数组(如 uploadedFiles = [])手动累积,并通过 Array.from(e.target.files) 转为真数组再合并去重。去重依据建议用 name + size + lastModified 组合,单靠 name 不可靠(同名不同内容文件很常见)。
- 每次触发
change后先清空input的值:e.target.value = '',否则连续选相同文件不会再次触发事件 - 检查
FileList是否为空(用户点取消时长度为 0),避免渲染空项 - 列表 DOM 元素需带唯一
data-file-id或key,方便后续删除或校验
如何在列表中显示文件大小和类型图标
文件大小直接取 file.size(单位字节),需格式化为 KiB/MiB:除以 1024 取整,保留一位小数即可,不必用 Intl.NumberFormat 增加体积。
类型图标没有标准映射,但可基于 file.type 做粗略判断:image/*、text/*、application/pdf 等可匹配,其余 fallback 到通用文档图标。注意 file.type 可能为空(如拖入无扩展名文件),此时应降级查 file.name.split('.').pop().toLowerCase()。
-
file.type是 MIME 类型,由浏览器根据扩展名推测,不可信但够用 - 避免对每个文件发起
URL.createObjectURL()预览——仅当需要缩略图或播放时才创建,用完记得URL.revokeObjectURL() - 大小单位统一用二进制前缀(KiB=1024),别混用 KB(1000)造成用户困惑
为什么用 FormData 提交时列表显示正常但后端收不到文件
列表展示和实际上传是两件事。展示只读 input.files,而提交需把 File 对象 append 到 FormData。常见坑是:append 时用了 file.name 当 key,但后端约定的字段名是 files[] 或 attachments,导致解析失败。
- 确认后端接收字段名,例如
formData.append('attachments', file),不是formData.append(file.name, file) - 多文件要循环 append,不要传整个
FileList——FormData.append()不接受类数组 - 如果用
fetch提交,确保没手动设置Content-Type头,否则浏览器无法自动写入 boundary - 列表里显示的文件名是前端视角,后端看到的是
Content-Disposition: form-data; name="attachments"; filename="xxx.jpg"中的filename,二者应一致
最易忽略的是:列表渲染后,用户可能手动删掉某几项,但没同步清理对应 uploadedFiles 数组,结果提交了本该剔除的文件。操作列表增删时,必须双向同步数据与视图。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











