Flask中request.files.get()取不到文件主因是前端未正确发送multipart/form-data:表单需设enctype="multipart/form-data",fetch/axios须用FormData构造体且不手动设Content-Type;文件保存前须用secure_filename()清洗文件名、确保UPLOAD_FOLDER存在并使用绝对路径;大文件需同步调大Flask的MAX_CONTENT_LENGTH和Nginx的client_max_body_size;多文件上传应使用getlist('file')而非get()。

Flask里request.files.get()取不到文件?
不是代码写错了,大概率是前端没发对 multipart/form-data。浏览器表单必须显式设 enctype="multipart/form-data",用 fetch 或 axios 时更得小心:不能直接传 JSON 对象,得用 FormData 构造体。
常见错误现象:request.files.get('file') 返回 None,但 request.form 能取到其他字段;或者报错 KeyError: 'file'。
- 检查 HTML 表单有没有写
<form enctype="multipart/form-data"> - 用
fetch上传时,必须这样写:const fd = new FormData(); fd.append('file', input.files[0]); fetch(..., { body: fd }) - 别在
FormData里手动加Content-Type头——浏览器会自动设为带 boundary 的multipart/form-data,加了反而破坏结构
request.files['file'].save() 保存失败或路径错乱?
直接调 save() 前,得先确认文件对象合法、目标目录存在且有写权限。Flask 默认不校验文件名安全性,../、空字节、Windows 非法字符都可能绕过,导致写到意外位置甚至覆盖系统文件。
使用场景:用户头像上传、Excel 导入、日志附件等需要落盘的场景。
立即学习“Python免费学习笔记(深入)”;
仅使用 Python 将 Claw Code 虚拟化框架与 OpenClaw 集成,提供 184 种工具和 200 多条命令,用于安全分析和代码质量...
- 永远用
secure_filename()处理原始filename:from werkzeug.utils import secure_filename;它只保留 ASCII 字母、数字、下划线、连字符,删掉所有路径分隔符 -
save()的路径必须是绝对路径,相对路径容易因工作目录变化出错;建议拼成os.path.join(UPLOAD_FOLDER, filename) - 保存前检查
UPLOAD_FOLDER是否存在:os.makedirs(UPLOAD_FOLDER, exist_ok=True)
大文件上传卡死或 413 Request Entity Too Large?
这是 Nginx 或 Werkzeug 默认限制惹的祸,不是 Python 代码问题。Werkzeug 默认只收 500KB 以内的表单数据(含文件),超了就直接 400;Nginx 更狠,默认 1MB 就拒收。
参数差异明显:Werkzeug 控制的是整个请求体上限(MAX_CONTENT_LENGTH),Nginx 控制的是客户端发来的原始字节流大小(client_max_body_size)。
- Flask 端加配置:
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024(16MB) - Nginx 配置里加:
client_max_body_size 16M;,并 reload:nginx -s reload - 别只改后端——前端也要加上传进度提示,否则用户点上传后干等 30 秒没反应,大概率点重试,造成重复提交
上传多个同名字段(如file[])怎么处理?
HTML 里写 <input type="file" name="file" multiple> 或多个 <input name="file">,后端拿到的不是单个 FileStorage,而是可迭代对象。直接用 request.files.getlist('file') 才能取全,用 .get() 只拿第一个。
性能影响:一次拿多个文件比循环调 get() 省事,也避免重复解析 multipart boundary。
-
files = request.files.getlist('file')返回list[FileStorage],每个都有filename、stream、save() - 注意:如果前端用
name="file[]"(带方括号),Werkzeug 不识别,会当成普通字符串键,必须统一用name="file" - 逐个保存时,记得对每个文件单独做
secure_filename()和路径拼接,别复用同一个变量名
文件名清洗和路径拼接这两步,最容易被跳过。哪怕测试时一切正常,上线后遇到中文名、空格、特殊符号,或者部署路径和本地不一致,立刻出问题。

















