文件上传:r.GetUploadFile 保存与参数获取
引言
头像、附件、导入文件……上传是 Web 服务常见需求。GoFrame 在 *ghttp.Request 上提供了简洁的上传 API:r.GetUploadFile 取单文件、r.GetUploadFiles 取多文件,配合表单参数一起读取。
概念
- 客户端请求:上传一般用
multipart/form-data表单提交,文件字段与普通字段同在一个请求里。 - 服务端接收:
r.GetUploadFile("字段名")返回*ghttp.UploadFile(没有该文件时返回 nil);r.GetUploadFiles("字段名")返回切片。 - 保存文件:
file.Save(目录, ...)把文件保存到指定目录并返回保存后的文件名;是否生成随机文件名、返回形态等细节以官方文档文件上传章节为准(本章示例采用官方文档中的常见写法)。 - 同时取参数:上传请求里的普通字段依旧可用
r.Get/r.GetForm读取。
代码示例
单文件上传 + 普通参数:
package main
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
func main() {
s := g.Server()
s.Group("/upload", func(group *ghttp.RouterGroup) {
group.POST("/avatar", func(r *ghttp.Request) {
// 1. 读取普通表单参数
remark := r.GetForm("remark").String()
// 2. 取上传文件(字段名须与表单一致)
file := r.GetUploadFile("file")
if file == nil {
r.Response.WriteJson(g.Map{"code": 1, "message": "未获取到上传文件"})
return
}
// 3. 保存到 upload/ 目录(第二个参数 true 表示使用随机文件名,避免重名覆盖)
// 返回文件名与错误;具体参数含义以官方文档为准
savedName, err := file.Save("upload/", true)
if err != nil {
r.Response.WriteJson(g.Map{"code": 1, "message": err.Error()})
return
}
r.Response.WriteJson(g.Map{
"code": 0,
"message": "上传成功",
"data": g.Map{
"remark": remark,
"savedName": savedName,
},
})
})
})
s.SetPort(8000)
s.Run()
}
测试可用 curl 的 -F(multipart 表单):curl -F "file=@/tmp/avatar.png" -F "remark=我的头像" http://127.0.0.1:8000/upload/avatar。
多文件上传用 GetUploadFiles 循环保存:
group.POST("/multi", func(r *ghttp.Request) {
files := r.GetUploadFiles("files")
if len(files) == 0 {
r.Response.WriteJson(g.Map{"code": 1, "message": "未获取到文件"})
return
}
var saved []string
for _, f := range files {
name, err := f.Save("upload/", true)
if err != nil {
r.Response.WriteJson(g.Map{"code": 1, "message": err.Error()})
return
}
saved = append(saved, name)
}
r.Response.WriteJson(g.Map{"code": 0, "saved": saved})
})
注意点
Save的目标目录需存在且有写权限,最好先os.MkdirAll;保存路径务必做隔离,避免覆盖与路径穿越。- 文件类型/大小校验不能只信前端:服务端应根据扩展名、内容或体积做二次校验(gvalid 也可用于表单字段校验)。
- 生产环境上传目录建议放到独立存储或对象存储,本地目录只作开发/单机演示。
GetUploadFile返回 nil 表示字段缺失,先判空再使用,避免空指针。
小结
GetUploadFile/GetUploadFiles 取文件、Save 落盘、GetForm 取附带参数,GoFrame 的上传链路十分精简。安全校验与存储策略需要结合业务加固。文件上传 API 的精确签名以官方文档 goframe.org 的文件上传章节为准。