关键在于:正确获取多文件、用 FormData append 添加文件及参数、用 fetch 或 XHR 发送且不手动设 Content-Type;HTML 启用 multiple,JS 遍历 files 并 append 到 FormData,fetch 自动设头,XHR 支持进度。

用 input type="file" 配合 FormData 实现带参数的多文件异步上传,关键在于三件事:正确获取多个文件、为每个文件单独或统一命名并附加参数、用 fetch 或 XMLHttpRequest 发送——且不手动设置 Content-Type。
HTML 中启用多选并预留参数位置
给文件输入框加上 multiple 属性,并确保有明确的 name(如 files[] 或通用名 file),便于后端识别为数组;额外参数不用塞进 URL 或 JSON,而是后续由 JS 添加到 FormData 中:
<input type="file" id="fileInput" multiple accept="image/*,.pdf">- 可配一个隐藏字段或普通输入框存业务参数,比如:
<input type="hidden" id="userId" value="8821">或<select id="category"><option value="report">报告</option></select>
JS 中收集文件与参数构建 FormData
监听 change 事件,遍历 input.files 得到所有 File 对象,再逐个或批量 append 到 FormData。普通参数也用 append() 加入,字段名需和服务端约定一致:
- 创建实例:
const formData = new FormData(); - 添加全部文件(同名字段,后端收为数组):
for (let file of files) formData.append('file', file, file.name); - 添加额外参数:
formData.append('user_id', document.getElementById('userId').value);
formData.append('category', document.getElementById('category').value);
formData.append('upload_time', Date.now()); - 注意:不要写
JSON.stringify(formData),也不要把 formData 包进另一个对象里
用 fetch 发起上传(推荐)或 XHR(需进度)
现代项目优先用 fetch,简洁可靠;若需显示单文件上传进度,则必须用 XMLHttpRequest,因 fetch 原生不支持上传事件:
立即学习“前端免费学习笔记(深入)”;
-
fetch 方式(无进度):
fetch('/api/upload', { method: 'POST', body: formData })
✅ 不设headers,浏览器会自动加正确的multipart/form-data及 boundary
❌ 不要加{ headers: { 'Content-Type': '...' } },否则破坏协议 -
XHR 方式(支持进度):
const xhr = new XMLHttpRequest(); xhr.upload.onprogress = e => { console.log(`已上传 ${e.loaded}/${e.total}`); };
需为每个文件单独发请求(若要分文件进度),或用并发池控制同时上传数(如最多 3 个)
服务端与兼容性提醒
后端收到的是标准 multipart 请求,字段名和文件名都按 FormData 中的 append 名称解析。前端兼容性方面:
-
FormData和multiple在 IE10+、所有现代浏览器中可用 - IE11 不支持
fetch,需降级用XMLHttpRequest - 大文件建议上传前校验
file.size,避免内存占用过高或触发 413 错误 - 若需拖拽上传,可监听
drop事件并从e.dataTransfer.files获取文件列表,处理逻辑相同



















