文件上传:GetUploadFile 使用
结论:文件上传用 r.GetUploadFile("字段名") 拿到 *ghttp.UploadFile 并调用 Save 落盘即可;务必先做类型/大小校验、限制请求体大小,并对落盘文件名做随机化处理,防止路径穿越与恶意文件(文件名/API 细节以官方文档为准)。
一、核心要点
- 单个文件:r.GetUploadFile("file");多个文件:r.GetUploadFiles("files") 返回切片。
- 前端表单需 enctype="multipart/form-data",字段名与代码一致。
- 安全清单:扩展名/Content-Type 白名单、大小上限、禁止信任原始文件名(随机化重命名、限制目录)、上传目录禁止直接执行脚本。
- 请求体大小:由 Server 相关配置限制(如请求体大小配置项,以官方文档为准),超出返回 4xx。
代码示例
func Upload(r *ghttp.Request) {
file := r.GetUploadFile("file")
if file == nil {
r.Response.WriteStatusExit(400, "缺少文件")
}
// 校验扩展名白名单等(此处省略实现)
// 保存到目录,返回落盘文件名
name, err := file.Save("/data/uploads")
if err != nil {
g.Log().Error(r.Context(), err)
r.Response.WriteStatusExit(500, "保存失败")
}
r.Response.WriteJson(g.Map{"name": name})
}
// 多文件上传
func Uploads(r *ghttp.Request) {
files := r.GetUploadFiles("files")
for _, f := range files {
if _, err := f.Save("/data/uploads"); err != nil {
g.Log().Error(r.Context(), err)
}
}
}
常见追问 / 记忆点
- 追问:如何限制只能传图片?→ 同时校验扩展名与内容类型,最好再做服务端解码探测,别只信客户端。
- 追问:文件名怎么防攻击?→ 不采用用户原始名直接拼路径,改为随机名/时间戳名落盘,目录固定。
- 记忆点:GetUploadFile 取文件、Save 落盘;安全三板斧“限大小、白名单、随机名”。