c.FormFile() 返回multipart.FileHeader获取文件名、大小和MIME类型,但仅限首个同名文件;多文件需c.MultipartForm();需手动解码filename、校验MIME、关闭文件句柄。

如何用 c.FormFile() 获取上传文件基本信息
直接调用 c.FormFile("file") 是最常用方式,它返回 *multipart.FileHeader,里面含 Filename、Size、Header 等字段。注意:这个函数只读取表单中第一个同名文件字段,且不自动保存文件到磁盘。
- 如果前端用
<input type="file" name="avatar">,后端必须用c.FormFile("avatar"),名字不匹配会返回nil和错误 -
FileHeader.Size是字节数,不是人类可读格式,需自己转成 KB/MB -
FileHeader.Header.Get("Content-Type")可取 MIME 类型,但不可信——浏览器可伪造,不能作为唯一校验依据
为什么 c.MultipartForm() 有时比 FormFile() 更合适
当一个表单项含多个同名文件(如 <input type="file" name="photos" multiple>),FormFile() 只返回第一个,必须用 c.MultipartForm() 才能拿到全部。
-
c.MultipartForm()返回*multipart.Form,其File字段是map[string][]*multipart.FileHeader - 若表单有
photos多文件字段,应写form.File["photos"],再遍历 slice - 调用
c.MultipartForm()前,Gin 默认会解析整个 multipart body,内存占用随文件总大小线性增长,大文件场景要小心
获取原始文件名时要注意的编码问题
用户上传的中文或带特殊符号的文件名,在 FileHeader.Filename 中可能被 URL 编码或乱码,尤其在 Chrome 或 Safari 下常见。
- Go 标准库对
filename*参数(RFC 5987)支持有限,部分浏览器用它传 UTF-8 文件名,但FileHeader.Filename不自动解码 - 稳妥做法:先检查
FileHeader.Header.Get("Content-Disposition"),手动解析filename*=UTF-8''xxx部分并用url.PathUnescape()解码 - 不要直接信任
Filename做路径拼接,否则可能触发路径遍历(如../../etc/passwd),务必 sanitize 文件名
文件属性和实际内容必须分开处理
FormFile() 和 MultipartForm() 都只提供元信息,不打开或读取文件内容。想校验文件类型或提取尺寸,得自己用 c.FormFile() 拿到 FileHeader 后,再调 FileHeader.Open() 得到 multipart.File(本质是 io.ReadCloser)。
立即学习“go语言免费学习笔记(深入)”;
-
Open()返回的文件句柄必须显式Close(),否则连接不释放,高并发下容易耗尽 fd - 若只查 MIME 类型,可用
http.DetectContentType(),但仅靠前 512 字节,对压缩包或加密文件不可靠 - 图像尺寸检测要用第三方库(如
github.com/h2non/bimg或image.DecodeConfig),但需注意io.LimitReader控制读取量,防止恶意超大文件阻塞


















