iris 的 uploadformfiles 仅处理 name="files" 的多文件字段,单文件需用 formfile 或手动解析;保存前须校验 mime 类型(读文件头)、扩展名、创建父目录并用绝对路径,大文件需设 maxrequestbodysize 和超时。

为什么 iris.Context.UploadFormFiles 不能直接用在 multipart/form-data 的普通表单里
因为 Iris 的 UploadFormFiles 默认只处理 enctype="multipart/form-data" 中带 name="files"(复数)的多文件字段,且要求字段名严格匹配。如果你前端传的是 name="image" 或 name="avatar" 这类单文件字段,调用它会返回空切片,不报错也不提示——这是最常踩的坑。
实操建议:
- 确认前端
<input type="file" name="image">的name属性值 - 改用
ctx.FormFile("image")获取单个文件,或用ctx.Request().MultipartReader()手动解析(适合自定义逻辑) - 别依赖
UploadFormFiles做单图上传,除非你主动把前端字段名改成files
保存文件前必须校验 Content-Type 和后缀名,否则可能执行恶意脚本
Iris 不自动过滤 MIME 类型,ctx.FormFile 返回的 *multipart.FileHeader 里 Header.Get("Content-Type") 可被客户端伪造,仅靠它判断图片类型不可信。真正安全的做法是读取文件头(magic bytes)。
实操建议:
- 用
file.Open()打开临时文件,读前 512 字节,传给net/http.DetectContentType或更严格的golang.org/x/image/bmp等包做二进制检测 - 同时比对文件扩展名:从
file.Filename提取后缀,只允许.jpg、.jpeg、.png、.webp - 拒绝
Content-Type: text/html却后缀为.jpg的情况——这大概率是绕过前端校验的攻击
ctx.SaveFormFile 的路径参数不支持相对路径,且默认不创建父目录
调用 ctx.SaveFormFile("image", "./uploads/test.jpg") 会报 open ./uploads/test.jpg: no such file or directory,因为 Iris 不自动 os.MkdirAll,且 . 在某些部署环境下(如 systemd 服务)指向不可预测的位置。
实操建议:
- 用绝对路径,例如
/var/www/myapp/uploads/,并通过环境变量注入(如os.Getenv("UPLOAD_DIR")) - 在保存前手动确保目录存在:
os.MkdirAll(uploadDir, 0755) - 生成唯一文件名(如
uuid.NewString() + filepath.Ext(file.Filename)),避免覆盖或路径遍历
大文件上传要调 iris.Configuration{FireMethodNotAllowed: true} 并设超时
默认配置下,Iris 使用标准 net/http.Server,但未显式限制请求体大小和读取超时。用户上传 200MB 视频却命名为 avatar.png,接口会卡住、吃光内存,还无法中断。
实操建议:
- 启动前设置:
app.Run(iris.Addr(":8080"), iris.WithConfiguration(iris.Configuration{MaxRequestBodySize: 10 (限制 10MB) - 为上传路由单独加中间件控制超时:
iris.LimitRequestBodySize(10 - 生产环境务必配反向代理(Nginx)的
client_max_body_size,避免请求根本到不了 Iris
文件上传看着简单,但 MIME 校验、路径构造、超时控制、并发写入这几个点,任何一个漏掉都可能变成线上事故。别省那几行 os.MkdirAll 或 io.CopyN 的代码。











