layui upload 组件不支持真正一次性多文件上传,multiple: true 仅允许多选,auto: true 会为每个文件单独发请求;需设 auto: false,手动用 formdata 合并文件后 fetch 提交。

layui 默认的 upload 组件不支持「真正意义上的一次性多文件上传」——即把多个文件打包进同一个 HTTP 请求体(multipart/form-data)发给后端。你设了 multiple: true,只是允许用户一次选多个文件;但若没关掉 auto: true,它会为每个文件单独发一个请求。
为什么 multiple: true + auto: true 不等于“一次性上传”
这是最常被误解的地方。开启 multiple: true 后,choose 回调里的 obj.files 或 obj.pushFile() 确实能拿到全部文件,但只要 auto: true(默认值),layui 就会遍历这些文件,对每一个都调一次内部上传逻辑,发出独立请求。
- 后端收到的是 N 个单文件请求,不是 1 个含 N 个文件的请求
-
done回调会触发 N 次,每次只带一个文件的结果 - 如果你的接口设计是接收
files[]字段(如 PHP 的$_FILES['files']),这种模式根本用不上 - 浏览器并发限制(通常 6 个同域请求)会让上传看起来“并行”,但这不是可控的批量行为
想真正一次性上传多个文件,必须绕过 obj.upload()
因为 layui 的 upload 模块不提供将多个 File 对象塞进一个 FormData 并提交的能力。你要自己构造请求:
- 设
auto: false,并在choose中缓存所有文件:var pendingFiles = Array.from(obj.files) - 绑定一个「上传」按钮,点击时手动创建
FormData - 对每个
File调用formData.append('files[]', file)(字段名必须和后端约定一致) - 额外参数(如
token、dir)也用formData.append()加入 - 用
fetch或$.ajax发送,不要设contentType—— 浏览器会自动生成带boundary的multipart/form-data头
示例关键片段:
choose: function(obj) {
pendingFiles = Array.from(obj.files);
},
// …… 另起一个按钮的 onclick
document.getElementById('uploadBtn').onclick = function() {
var formData = new FormData();
pendingFiles.forEach(function(file) {
formData.append('files[]', file);
});
formData.append('token', 'xxx');
fetch('/api/upload', { method: 'POST', body: formData })
.then(r => r.json())
.then(console.log);
};
如果坚持走 layui 的 obj.upload() 流程,要注意这些坑
这适合后端已适配「单文件单请求」的场景,但仍有细节容易翻车:
-
number: 5不是“总共最多传 5 个”,而是“单次点击选择框最多选 5 个”——用户点两次,照样能凑出 10 个待上传文件 -
data参数是静态对象,不会为每个文件动态求值;想传不同参数(如每张图带不同分类 ID),得在before回调里用FormData手动拼 -
done不触发?先检查后端是否返回标准 JSON,且含code: 0,Content-Type: application/json,无 BOM/空格/HTML 注释 - IE10/11 下上传失败,大概率是跨域头缺失或
X-Requested-With未设置,原生FormData支持也弱于现代浏览器
真正的难点不在“怎么写代码”,而在于前后端约定是否对齐:前端用 files[] 还是 fileList,后端是循环处理 $_FILES 还是直接解析 multipart body —— 这个契约一旦错位,所有上传都会静默失败或只传第一个文件。











