使用 router.post 配置文件上传路由,需配合 multipart/form-data 表单、预设 r.maxmultipartmemory 内存限制,并确保 c.formfile() 字段名与 html input 的 name 属性完全一致,否则返回 400 或空文件。

直接用 router.POST 配置即可,但必须配合 multipart/form-data 表单、显式设置内存限制、正确提取字段名——漏掉任意一项都会导致 400 或空文件。
路由声明必须用 POST + 显式路径
Gin 不支持 GET 上传,router.POST("/upload", handler) 是唯一可行方式。别写成 GET 或带参数的动态路由(如 /upload/:id),c.FormFile() 依赖原始 multipart body,路径参数会干扰解析。
- ✅ 正确:
r.POST("/upload", uploadHandler) - ❌ 错误:
r.GET("/upload", ...)、r.POST("/upload/:uid", ...) - ⚠️ 注意:路径末尾斜杠不自动重定向,
/upload/和/upload是两个不同路由
c.FormFile() 的字段名必须和 HTML name 属性完全一致
c.FormFile("file") 中的 "file" 是表单里 <input type="file" name="file"> 的 name 值,大小写、下划线、中横线都敏感。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- HTML 写
name="avatar"→ Go 里必须用c.FormFile("avatar") - 多文件时若前端用
name="files",后端不能写成c.FormFile("files")(那是单文件 API),得用c.MultipartForm()拿form.File["files"] - 常见错误:浏览器开发者工具看到请求体里有文件,但
c.FormFile返回nil—— 八成是 name 对不上
必须提前设 r.MaxMultipartMemory,否则大文件直接 400
Gin 默认只允许 32MB 以内 multipart 数据进内存,超限就拒绝请求并返回 http.StatusBadRequest,不会进 handler。这个值必须在注册路由前设置。
- 设 8MB:
r.MaxMultipartMemory = 8 - 设 100MB:
r.MaxMultipartMemory = 100 - ⚠️ 重点:这行代码要放在
r.POST(...)之前,放错位置无效 - 注意:这只是内存缓冲上限,真正保存到磁盘不受此限,但过大会拖垮服务
上传失败时 error 不一定来自网络,常是字段缺失或格式错
c.FormFile() 报错信息很泛,比如 "http: no such file" 并非文件不存在,而是表单没提交该字段;"invalid header" 往往是 content-type 没设对或用了 application/json。
- 检查点:HTML 是否有
enctype="multipart/form-data"?没有就纯文本提交,后端收不到二进制 - 检查点:是否多个
<input type="file">用了相同name?会导致只取第一个 - 调试建议:先打印
c.Request.MultipartReader()是否为 nil,再查c.Request.FormValue看其他字段是否正常
真正麻烦的不是写几行代码,而是前端发的请求格式和后端期待的解析逻辑之间那层薄薄的、容易被忽略的契约——name 对不上、enctype 忘写、MaxMultipartMemory 放错顺序,三个地方任一出错,c.FormFile 就静默失效。










