Beego 中应使用 GetFile 获取上传文件,参数名需与表单 input 的 name 一致,并确保 enctype="multipart/form-data";可直接获取文件名、大小和句柄,避免手动解析导致的乱码、OOM 或文件名转义等问题。

用 GetFile 获取单个上传文件,别手动解析 multipart
Beego 已封装好 GetFile 方法,直接从 *multipart.FileHeader 中提取原始文件名、大小和句柄,无需自己调用 r.MultipartReader() 或 ParseMultipartForm。手动解析不仅容易丢掉 Filename(尤其含中文时),还会绕过 Beego 的内存/临时文件自动管理逻辑。
常见错误现象:header.Filename 为空或变成随机字符串;上传大文件时服务卡死或 OOM;保存后文件名被转义成 %E6%96%87%E4%BB%B6.jpg。
-
GetFile("file")的参数名必须和 HTML 表单中<input type="file" name="file">的name值严格一致 - 确保表单设置了
enctype="multipart/form-data",否则GetFile返回nil且无报错 - 上传前建议校验
header.Size,避免超限(如限制 ≤20MB):if header.Size > 20 - 原始文件名可直接用于保存,但需过滤路径遍历风险:用
path.Base(header.Filename)截取纯文件名,再拼接安全目录
用 GetFiles 处理多文件上传,multiple 属性不能少
前端 <input type="file" multiple name="files"> 提交后,后端必须用 GetFiles("files"),而不是多次调用 GetFile —— 后者只会拿到第一个文件。
常见错误现象:只存下第一个文件;循环中 file.Open() 后忘记 defer file.Close(),导致文件句柄泄漏;用 os.Create 直接写入时未检查目标目录是否存在。
-
GetFiles返回[]*multipart.FileHeader,每个元素都带独立的Filename和Size - 每个文件需单独调用
Open()获取读取句柄,且应在循环内完成Close() - 保存路径建议用
filepath.Join("uploads", fmt.Sprintf("%d-%s", time.Now().UnixNano(), path.Base(h.Filename)))避免重名和路径注入 - 若需并发保存,注意 Beego 默认不启用 goroutine 安全,避免共用同一个
dst *os.File
控制上传大小和缓存行为,靠 web.MaxMemory 和 MaxUploadSize
Beego 默认把 ≤64MB 的上传内容缓存在内存,超过部分落盘为临时文件。这两个配置决定实际行为边界,不是“最大允许值”那么简单。
常见错误现象:上传 100MB 文件时服务无响应;并发上传多个小文件总和超限却被放行;调整了 MaxUploadSize 却没生效。
web.MaxMemory = 1 (即 4MB)应在 <code>main.go初始化阶段设置,早于beego.Run()-
MaxUploadSize是所有上传文件总大小上限(非单个),单位字节,可在app.conf写为maxuploadsize = 52428800(50MB) - 若
MaxMemory > MaxUploadSize,Beego 会忽略MaxUploadSize,所以务必让前者 ≤ 后者 - 临时文件默认存在系统
os.TempDir(),生产环境建议通过os.Setenv("TMPDIR", "/data/tmp")指向独立磁盘分区
中文文件名保存和安全性,path.Base + 白名单后缀是底线
客户端传来的 header.Filename 可能含 ../、空字符、控制符或非法扩展名,直接拼接路径等于开放任意文件写入。
常见错误现象:上传 ../../../etc/passwd 覆盖系统文件;保存 shell.php 导致 RCE;浏览器下载时中文名显示为乱码或截断。
- 强制用
path.Base(header.Filename)剥离路径,再用正则^[a-zA-Z0-9\u4e00-\u9fa5._-]{1,128}$过滤非法字符 - 按 MIME 类型或后缀做白名单校验(如只允许
.jpg/.png/.pdf),用strings.HasSuffix(strings.ToLower(name), ".pdf") - 保存时不依赖原始后缀,而用
mime.TypeByExtension或http.DetectContentType二次确认内容真实类型 - 若需保留中文名供下载,保存用 UUID 命名,数据库记录原始名;下载时用
Content-Disposition: attachment; filename*=UTF-8''xxx.pdf设置头


















