fiber 框架不内置 multipart 解析器,ctx.formvalue() 仅支持 application/x-www-form-urlencoded 和 text/plain,对 multipart/form-data 直接跳过,故无法获取文件字段;需显式调用 ctx.multipartform() 解析。

Fiber 框架本身不内置 Multipart 解析器,必须显式调用 ctx.MultipartForm() 或手动读取 ctx.Request().multipartReader,否则 ctx.FormValue()、ctx.BodyParser() 等方法完全无法获取文件字段或混合表单数据。
为什么 ctx.FormValue() 拿不到文件字段?
Fiber 的 ctx.FormValue() 仅解析 application/x-www-form-urlencoded 和 text/plain 请求体,对 multipart/form-data 直接跳过 —— 它压根不尝试解析 multipart boundary 和 part 结构。哪怕你写了 enctype="multipart/form-data",只要没调用 multipart 专用方法,文件字段就彻底丢失。
-
ctx.FormValue("file")返回空字符串,不是null,也不报错,容易误判为“用户没传” -
ctx.BodyParser()同样失效,它只处理 JSON、XML、URL-encoded 这类扁平结构 - 普通文本字段(如
name)在 multipart 中也藏在 part 里,不走 multipart 解析就拿不到
ctx.MultipartForm() 是最简可用方案
这是 Fiber 封装好的标准入口,内部调用 http.Request.ParseMultipartForm(),返回 *multipart.Form,包含 Value(文本字段 map)和 File(文件头 map)两个字段。
- 必须在读取任何 body 前调用,否则后续
ctx.MultipartForm()会返回http.ErrNotMultipart - 默认限制内存缓冲为 32MB,超出部分写入临时磁盘;可通过
f.App().Config().Server.Header.MaxMultipartMemory = 64 调整 - 示例:
form, err := ctx.MultipartForm() if err != nil { ctx.Status(400).SendString("parse failed: " + err.Error()) return } name := form.Value.Get("name") // 文本字段 files := form.File["file"] // []*multipart.FileHeader
用 ctx.SaveFile() 快速存文件,但注意路径安全
ctx.SaveFile() 是 Fiber 提供的便捷封装,自动打开 multipart.FileHeader 并保存到指定路径,省去自己 Open() 和 Copy() 的步骤。
- 第二个参数是目标路径,**不会自动创建父目录**,若
/uploads/2026/09/不存在会报no such file or directory - 文件名未做任何过滤,攻击者可传
../../../etc/passwd类路径,必须校验fileHeader.Filename是否为合法 basename(例如用path.Base()提取后缀再白名单校验) - 不支持直接存到内存或流式处理大文件;如需控制存储逻辑(如分片、加水印),得用
fileHeader.Open()手动读取
大文件或自定义处理必须用 ctx.MultipartForm() + Open()
当需要校验文件内容、计算哈希、限制单个文件大小、或避免临时磁盘写入时,不能依赖 SaveFile(),必须手动操作 multipart.FileHeader。
-
fileHeader.Size是客户端声明的大小,可能被篡改,真实大小需在io.Copy()时累计校验 -
fileHeader.Open()返回multipart.File(本质是io.ReadCloser),必须defer f.Close(),否则句柄泄漏 - 若想限制总请求大小(比如整个 multipart 不超过 100MB),需在
app.Use(func(c *fiber.Ctx) error { ... })中提前检查c.Request().Header.ContentLength(),因为MultipartForm()不校验整体长度
真正容易被忽略的是:Fiber 默认不限制 multipart 总大小,也不校验上传路径合法性 —— 这两点都得你自己补,框架只管“能跑”,不管“跑得安全”。











