因为Flask中request.files['name']仅返回同名文件的第一个,正确做法是用request.files.getlist('name')获取全部FileStorage对象;必须确保前端enctype="multipart/form-data"、name一致且含multiple,上传前校验类型、大小、路径安全,并用uuid重命名防冲突。

Flask里用request.files接收多图时为什么只拿到一个文件?
因为默认情况下,HTML表单中多个同名<input type="file" multiple>上传的文件,在Flask中不会自动聚合成列表——request.files['images']只会返回第一个文件(FileStorage对象),其余被静默丢弃。
正确做法是改用request.files.getlist():
uploaded_files = request.files.getlist('images')关键点:
-
getlist()是Flask对MultiDict的扩展方法,专为处理同名多值设计 - HTML input必须带
name="images"且不含multiple属性以外的干扰(比如不能写成name="images[]",PHP风格在Flask里无效) - 如果前端用了
enctype="multipart/form-data"但忘了设method="POST",request.files会为空字典
保存多图前必须校验文件类型和大小,否则直接崩溃
用户可能传.exe、超大视频或空文件,不拦截会导致磁盘写入失败或安全风险。Flask本身不校验,得自己做:
立即学习“Python免费学习笔记(深入)”;
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
- 用
file.filename.rsplit('.', 1)[1].lower()取后缀,别信file.content_type(可伪造) - 检查
file.filename是否为空字符串(空上传)或含../路径遍历字符 - 调用
file.seek(0, 2)获取长度再file.seek(0)重置指针,避免后续save()读不到内容 - 单文件建议限制≤5MB,总上传量用
sum(f.seek(0,2) for f in uploaded_files)预判
示例片段:
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
for file in uploaded_files:
if not file or not file.filename:
continue
ext = file.filename.rsplit('.', 1)[1].lower() if '.' in file.filename else ''
if ext not in ALLOWED_EXTENSIONS:
return "Unsupported file type", 400
file.seek(0, 2)
if file.tell() > 5 * 1024 * 1024:
return "File too large", 400
file.seek(0) # reset before save
并发上传多图时用uuid4()重命名比datetime更可靠
用时间戳命名(如f"{int(time.time())}_{file.filename}")在高并发下极易冲突,尤其Nginx+Gunicorn多worker时系统时间几乎同步。
-
uuid.uuid4()生成的随机字符串碰撞概率极低,且无需依赖文件系统状态 - 保留原始扩展名(从
file.filename提取),不要硬编码.jpg,否则webp等格式会损坏 - 路径拼接务必用
os.path.join(UPLOAD_FOLDER, safe_filename),禁用字符串拼接防止目录穿越 - 确保
UPLOAD_FOLDER目录存在且Web服务器进程有写权限(常见坑:Linux下忘记chown www-data:www-data)
前端<form>配置错一个属性,后端就收不到任何文件
最常被忽略的是enctype——即使写了method="POST",缺了enctype="multipart/form-data",request.files永远为空字典,且无报错提示。
- 完整正确写法:
<form method="POST" enctype="multipart/form-data"> -
<input type="file" name="images" multiple>中的name必须和后端getlist('images')完全一致(区分大小写) - 若用AJAX上传,
FormData对象需显式append('images', file)每个文件,不能append('images', filesList) - 测试时用
curl -F 'images=@a.jpg' -F 'images=@b.png' http://localhost:5000/upload验证后端逻辑,绕过前端干扰
多图上传真正的复杂点不在代码量,而在校验链路必须全通:前端属性→传输协议→后端解析→文件扫描→存储隔离,任意一环漏判,轻则功能失效,重则服务被拖垮。

















