PostValue仅返回同名表单字段的第一个值,获取全部需用PostValues;JSON数组必须用ReadJSON解析,不可混用;multipart中PostValues仍有效但顺序不保证;嵌套表单需手动解析。

PostValue 无法直接获取数组,得用 PostValues
Iris 的 c.PostValue("items") 只返回第一个匹配值的字符串,哪怕前端提交了多个同名字段(如 <input name="items"> 多次出现),它也只取第一个。真正要拿到全部,必须用 c.PostValues("items") —— 它返回 []string,这才是表单数组的正确入口。
常见错误现象:前端发了 items=a&items=b&items=c,后端用 PostValue 打印出来永远是 "a",还以为数据丢了。
- 前端确保用相同
name属性重复提交,例如:<input name="tags" value="go"><input name="tags" value="web"><input name="tags" value="iris"> - 后端用
c.PostValues("tags")得到[]string{"go", "web", "iris"} - 如果想转成 int 切片,得手动遍历转换,Iris 不提供
PostValuesInt这类批量类型转换函数
JSON 请求体里的数组要走 c.ReadJSON,不是 PostValue
很多人混淆“表单提交”和“JSON 提交”。如果你用 fetch 或 axios 发的是 Content-Type: application/json,那根本进不到 PostValue 或 PostValues 的逻辑里——这些函数只处理 application/x-www-form-urlencoded 和 multipart/form-data。
此时必须用 c.ReadJSON(&payload),且 payload 结构体字段得是切片类型:
type UserForm struct {
Name string `json:"name"`
Roles []string `json:"roles"` // 前端 JSON 里 "roles": ["admin", "user"]
}
然后在 handler 里:
var form UserForm
if err := c.ReadJSON(&form); err != nil {
c.StatusCode(400)
c.WriteString("invalid json")
return
}
// form.Roles 就是 []string 类型的切片
- 别试图对 JSON 请求体调用
PostValues,它会返回空切片 -
ReadJSON默认支持嵌套结构、指针字段、omitempty 等标准 JSON 标签行为 - 如果前端传的是纯数组(如
["a","b"]而非对象),需定义var roles []string直接解码
文件上传 + 表单混合时,数组字段仍走 PostValues,但顺序可能错乱
当路由同时接收文件(multipart/form-data)和普通字段时,Iris 仍把同名文本字段归为一组,PostValues 依然可用。但要注意:浏览器对 multipart 字段的序列化顺序不保证,尤其跨浏览器时。
比如你有三个 <input name="ids"> 和一个 <input type="file" name="avatar">,Chrome 可能先发所有 ids 再发 avatar,Safari 可能穿插着发——但这不影响 PostValues("ids") 拿到全部值,Iris 内部已聚合。
- 只要字段名一致,
PostValues总能收全,无需担心顺序 - 但不要依赖
PostValue获取“第几个”值,它没有索引语义 - 若需强顺序(如带序号的配置项),建议前端改用 JSON 格式提交,或加索引前缀(
item[0],item[1]),后端再解析
自定义解析器:处理带结构的表单数组(如 item[name]、item[value])
有些前端框架(如 Vue + FormKit)会把数组序列化成带方括号的键名:user[0][name]=alice&user[0][age]=25&user[1][name]=bob。Iris 原生不解析这种嵌套表单,PostValues 只返回原始键名列表,不会自动组装结构。
这时得自己写解析逻辑,或借助第三方库(如 github.com/mikespook/gorbac 不适用,得用通用表单解析器)。最简方案是扫描所有 PostValue 键,按正则提取索引和字段:
re := regexp.MustCompile(`user\[(\d+)\]\[(\w+)\]`)
for _, key := range c.FormKeys() {
if matches := re.FindStringSubmatchGroup([]byte(key)); matches != nil {
idx := string(matches[0]) // "0"
field := string(matches[1]) // "name"
val := c.PostValue(key) // "alice"
// 手动存入 map[idx] = map[field]val
}
}
- Iris 没有类似 PHP 的
$_POST['user'][0]['name']自动展开机制 - 别指望
c.FormValue或c.FormValues能理解方括号语法 - 如果项目频繁遇到这类结构,建议统一约定为 JSON 提交,省去解析成本


















