文件上传: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 落盘;安全三板斧“限大小、白名单、随机名”。
笔记加载中…