文件上传: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 的文件上传章节为准。

笔记加载中…