gin中文件上传需按场景选择c.formfile或c.multipartform:单文件用c.formfile并校验name和enctype;多文件同名必须用c.multipartform解析切片;多文件不同名可多次调用c.formfile;保存前须校验扩展名、大小和路径穿越。

要在Gin服务中接收前端上传的单个或多个文件,并安全落盘,必须区分使用c.FormFile与c.MultipartForm,否则会出现nil文件、400错误或内存暴涨问题。
单文件上传:用c.FormFile获取并保存
这一步操作起来很简单,直接调用c.FormFile("file")就能拿到文件头,适合头像、简历等明确单字段场景。
第一步:在路由处理函数中调用c.FormFile("file"),参数名必须和HTML表单里<input name="file">的name属性完全一致,大小写敏感,拼错一个字母就返回nil。
第二步:检查err是否为nil,若不为nil说明没收到文件——常见原因是前端没设enctype="multipart/form-data",或Postman里选了x-www-form-urlencoded却往form-data里填内容。
第三步:调用c.SaveUploadedFile(file, dst)保存,dst路径需包含完整文件名,比如"./uploads/" + file.Filename;注意目录./uploads/必须提前存在,否则保存会失败。
多文件同名上传:用c.MultipartForm批量解析
当用户一次选中多个文件(<input type="file" name="photos" multiple>),后端必须用c.MultipartForm()才能拿到全部文件,c.FormFile只返回第一个。
方法一:先调form, err := c.MultipartForm(),再取form.File["photos"]得到[]*multipart.FileHeader切片。
方法二:遍历切片,对每个file调用c.SaveUploadedFile(file, "./uploads/"+file.Filename)保存;注意不要在循环里重复创建同名文件,否则后上传的会覆盖前一个。
关键提醒:c.MultipartForm()会一次性把全部文件header和所有表单值都加载进内存,大并发时可能OOM;如果只处理文件不读其他字段,优先用多次c.FormFile。
多文件不同名上传:逐个调用c.FormFile
前端有多个独立文件输入框,比如<input name="avatar">、<input name="idcard">,后端无需解析整个multipart,直接分次取即可。
先取avatar, _ := c.FormFile("avatar"),再取idcard, _ := c.FormFile("idcard"),各自保存到不同子目录下,互不影响。
这比c.MultipartForm()更轻量,也不会因某个字段缺失导致整个解析失败。
保存前务必校验三件事:文件扩展名是否在白名单内、Size是否超过预设阈值、Filename是否含路径穿越字符(如../),否则可能被写入任意目录甚至执行RCE。











