beego文件上传需同时配置全局请求体限制与单文件校验:在app.conf中设maxmemory=1<<20、maxuploadsize=10<<20,控制器内再校验header.size≤5<<20,并用filepath.join安全保存。

在Beego框架中实现文件上传并确保服务端不因超大文件请求崩溃,必须同时配置全局请求体限制与单文件尺寸校验,否则仅靠控制器内判断会错过内存已耗尽的临界点。
配置全局请求体大小限制
打开 conf/app.conf 文件,在 [server] 区块下添加:
maxmemory = 1
MaxUploadSize = 10
【maxmemory 必须小于 MaxUploadSize,否则超出部分无法进入临时文件流程,直接被拒绝】
这两项共同决定:小于 1MB 的文件走内存;1MB~10MB 的文件,前 1MB 在内存、其余写入临时目录;超过 10MB 的请求,Beego 在解析前就返回 HTTP 413 状态码,不进 Controller。
编写上传控制器
在 controllers/ 目录下新建 upload_controller.go:
方法一:基础上传(保留原始文件名)
package controllers
import (
"github.com/astaxie/beego"
)
type UploadController struct {
beego.Controller
}
func (c *UploadController) Post() {
file, header, err := c.GetFile("myfile")
if err != nil {
c.Ctx.WriteString("未选择文件或字段名错误")
return
}
defer file.Close()
// 此处 header.Size 是安全可读的,不触发实际读取
if header.Size > 5
c.Ctx.WriteString("单个文件不能超过 5MB")
return
}
err = c.SaveToFile("myfile", "static/upload/"+header.Filename)
if err != nil {
c.Ctx.WriteString("保存失败:" + err.Error())
return
}
c.Ctx.WriteString("上传成功")
}
方法二:带路径自动创建与安全重命名
第一步:在 Post 方法开头加入目录创建逻辑
uploadDir := "static/upload/" + beego.Now().Format("2006/01/02/")
os.MkdirAll(uploadDir, 0755)
第二步:生成唯一文件名,避免覆盖和路径遍历
ext := path.Ext(header.Filename)
safeName := fmt.Sprintf("%d_%x%s", time.Now().UnixNano(), md5.Sum([]byte(header.Filename)), ext)
第三步:拼接完整路径并保存
fpath := filepath.Join(uploadDir, safeName)
err = c.SaveToFile("myfile", fpath)
【务必用 filepath.Join 而非字符串拼接,防止 header.Filename 含 ../ 绕过目录限制】
注册路由
在 routers/router.go 中添加:
beego.Router("/upload", &controllers.UploadController{}, "post:Post")
注意:不要使用 RESTful 路由如 "*:Post",该写法会匹配所有 HTTP 方法,导致 GET 请求也进入 Post 方法体。
前端表单示例
确保 HTML 表单满足 multipart/form-data 要求:
name 属性值必须与控制器中 c.GetFile("myfile") 的参数完全一致,大小写敏感。











