多文件上传核心是正确操作filelist与file对象;需设multiple属性、用户配合多选或拖放,用array.from转数组处理,校验name/size/type/lastmodified,避坑去重、预览、formdata构造及服务端接收。

多文件上传的核心在于正确理解并操作 FileList 与 File 对象。它们不是普通数组,但行为接近;不能直接用 map 或 forEach(除非转成数组),但支持索引访问、length 和遍历。关键不在“能不能选多个”,而在于“选完之后怎么安全、可控地用”。
如何获取并确认用户选中的多个文件
给 <input type="file"> 添加 multiple 属性是前提,但仅此不够:
- 用户需主动配合:Windows/Linux 按住 Ctrl 多选,macOS 按住 Command;或直接拖入多个文件(若支持拖放)
-
input.files返回的是FileList,它有length、数字索引(如files[0])、item(i)方法,但没有数组原型方法 - 建议第一时间检查
files.length,避免空上传;也可用Array.from(files)或[...files]转为真数组,方便后续过滤、去重等操作
每个 File 对象能提供哪些真实可用信息
File 是 Blob 的子类,继承了基础二进制能力,同时补充了用户视角的关键元数据:
-
name:仅文件名,不含路径(浏览器出于安全限制,不暴露本地路径) -
size:字节数,可用于大小校验(如限制单个文件 ≤ 10MB) -
type:MIME 类型(如"image/png"),但不可信——后缀可伪造,type由浏览器根据文件头或扩展名推测,需服务端二次校验 -
lastModified:时间戳(毫秒),比lastModifiedDate更推荐使用 - 注意:
File对象本身不包含内容,读取内容需借助FileReader或直接提交给FormData
常见处理动作与避坑点
实际开发中,几个高频操作容易出错:
-
去重逻辑不能只比
name:同名文件可能来自不同目录或不同修改时间,应结合size+lastModified粗略判断,或计算文件 hash(适合小文件) -
上传前预览图片?别直接用
file.name:需用URL.createObjectURL(file)生成临时 blob URL,赋值给<img src>;记得上传成功后调用URL.revokeObjectURL()释放内存 -
构造 FormData 时要传对参数:循环添加文件应使用
formData.append('files', file, file.name),第三个参数显式指定服务端接收的原始文件名,避免中文乱码或空格问题 -
服务端接收必须匹配前端结构:若前端用
append('files', file)多次追加,后端需按数组方式接收(如 Spring Boot 的@RequestParam MultipartFile[] files),而非单个MultipartFile
扩展能力:不只是点击选择
FileList 不只来自 <input>,还可来自其他交互场景,拓宽上传入口:
-
拖放上传:监听
drop事件,从event.dataTransfer.files获取FileList,体验更自然 -
目录上传:添加
webkitdirectory属性(Chrome/Safari 支持),可一次性选中整个文件夹,files中会包含带路径层级的File对象(webkitRelativePath属性可用) -
剪贴板粘贴图片:监听
paste事件,检查event.clipboardData.items中是否有type为image/*的File,适合截图即传场景











