Beego中Controller通过GetFile()接收单文件、GetFiles()接收多文件,需前端form设enctype="multipart/form-data"且name匹配;调用前建议显式ParseForm(),保存时须预建目录并校验文件类型与大小。

Beego 中 Controller 怎么接收上传的文件
Beego 的文件上传入口在 Controller 实例的 GetFile() 方法,它底层调用的是 http.Request.FormFile()。必须确保前端表单是 enctype="multipart/form-data",且 input 的 name 属性与 GetFile() 的参数一致。
常见错误是直接读 r.Body 或误用 GetString() —— 这些拿不到文件内容,只会返回空或报错 http: no such file。
-
GetFile("myfile")中的"myfile"必须和 HTML 里<input type="file" name="myfile">完全匹配(区分大小写) - 上传前需调用
c.ParseForm()(Beego 1.12+ 通常自动调用,但显式写上更稳妥) - 若表单含多个同名
input,GetFile()只返回第一个;要处理多文件,得用c.GetFiles()
GetFiles() 如何处理多个同名文件上传
当 HTML 使用 <input type="file" name="files" multiple> 或多个 <input type="file" name="files"> 时,GetFiles("files") 返回 []*multipart.FileHeader,每个元素对应一个上传文件的元信息。
注意:Beego 不会自动解析 multiple 属性,必须用 GetFiles(),不是 GetFile() —— 后者只取首个,其余被丢弃。
立即学习“go语言免费学习笔记(深入)”;
- 每个
*multipart.FileHeader包含Filename、Size、Header,但不包含文件内容 - 用
c.SaveToFile("files", dstPath)可一键保存(推荐用于简单场景) - 若需校验类型或流式处理,用
file.Open()获取io.ReadCloser,记得defer f.Close()
保存文件时路径和权限要注意什么
SaveToFile() 的第二个参数是**相对路径**,以 Beego 应用启动目录为基准,不是相对于 static 或 views 目录。例如传入 "uploads/test.jpg",实际保存到 $APP_ROOT/uploads/test.jpg。
容易踩的坑:目录不存在时 SaveToFile() 会静默失败并返回 nil error,但文件根本没存进去 —— 它不会自动创建父目录。
- 务必提前用
os.MkdirAll("uploads", 0755)创建目标目录 - Linux 下注意运行 Beego 进程的用户是否有写权限,否则报
permission denied - 不要把上传路径写成绝对路径如
/var/www/uploads/,Beego 不校验路径合法性,可能被构造恶意路径遍历(如../../../etc/passwd),需手动过滤../
如何安全地校验上传文件类型和大小
仅靠前端 accept="image/*" 或后端检查 Header.Get("Content-Type") 完全不可信 —— MIME 类型由浏览器提供,可轻易伪造。真实类型必须读文件头(magic bytes)。
Beego 没内置 magic number 校验,需自己实现或引入轻量库如 gabriel-vasile/mimetype。同时,FileHeader.Size 是可信的(由 multipart 解析器计算),可用于限制体积。
- 在调用
GetFile()或GetFiles()后立即检查fh.Size > 10 * 1024 * 1024(如限制 10MB) - 用
f, _ := fh.Open(); defer f.Close()读前 512 字节,传给mimetype.Detect()判断真实类型 - 避免用
filepath.Ext(fh.Filename)做白名单校验,攻击者可上传shell.php.jpg绕过
Beego 的文件上传机制本身很轻量,但安全边界全靠开发者手动补全 —— 路径清理、类型探测、目录预建、权限检查,缺一不可。最常被忽略的是 SaveToFile() 对不存在目录的静默失败,建议封装一层带 MkdirAll 和错误 panic 的保存函数。


















