c.FormFile()仅支持单文件同步提交,无刷新上传需AJAX配合正确enctype、method及自动Content-Type;须校验file非nil、路径存在、大小合规,并调大MaxMultipartMemory与Nginx限制。

为什么直接用 c.FormFile() 不够用
因为 c.FormFile() 只能处理单个文件字段,且默认依赖表单同步提交——浏览器会整页跳转或刷新。无刷新上传必须走 AJAX(XMLHttpRequest 或 fetch),而 Gin 本身不拒绝这类请求,但需确保后端能正确解析 multipart/form-data 的二进制流,且前端不破坏原始格式。
前端必须设对这三项:enctype、method、Content-Type
常见错误是用 fetch 发送 JSON 数据体却期望后端收到文件,或者漏掉 enctype="multipart/form-data" 导致后端收不到 $_FILES 类似结构(Go 中即 c.FormFile 返回 nil)。
- HTML 表单必须显式写
<form enctype="multipart/form-data" method="POST"> - 若用
fetch,不能手动设置Content-Type—— 浏览器会自动添加带 boundary 的multipart/form-data;设了反而会破坏解析 - 字段名(如
"file")必须和后端c.FormFile("file")中的字符串完全一致,区分大小写
c.SaveUploadedFile() 前要检查临时文件是否存在
Gin 解析 multipart 时会把文件暂存到内存或临时目录,但若上传中断、字段名错、或客户端未发送文件,c.FormFile() 返回的 file 可能为 nil,此时调 c.SaveUploadedFile() 会 panic。必须先判空再操作。
- 永远用
if file, err := c.FormFile("file"); err != nil { ... }包裹逻辑 - 错误码建议返回
http.StatusBadRequest(400)而非 500,因为多数是前端传参问题 - 保存路径(如
"./uploads/" + file.Filename)需确保目录存在,否则SaveUploadedFile返回open ./uploads/xxx: no such file or directory - 注意
file.Size单位是字节,可在此处加大小限制(比如 >10MB 就直接拒绝)
大文件上传要调 r.MaxMultipartMemory 和 Nginx 配置
Gin 默认只允许 32MB 内存缓存 multipart 数据,超限会报 http: request body too large;但更常见的是反向代理(如 Nginx)先拦住了请求,报 413 Request Entity Too Large。
- 在
main()初始化路由前设置:r.MaxMultipartMemory = 100 - Nginx 需配
client_max_body_size 100M;,并 reload - 若用前端分片上传(如
spark-md5+ 合并),Gin 接口本身不变,但需额外实现分片接收、校验、合并逻辑——这不是FormFile能覆盖的场景
enctype,多一个手动 Content-Type,就卡在第一步。


















