ctx.urlparam() 用于获取路径参数而非查询参数,正确获取 query string 应用 ctx.url().query().get()、ctx.formvalue() 或 ctx.request().url.query()["key"];类型转换和默认值需手动处理,注意中文编码与参数长度防护。

ctx.URLParam() 是错的,别用它取查询参数
很多人看到 ctx.URLParam() 就以为是取 ?id=123 这类参数,结果返回空字符串。其实它根本不是干这个的——它只解析 URL 中的路径参数(比如 /user/{id} 里的 id),和查询参数完全无关。真正该用的是 ctx.URL().Query() 或更直接的封装方法。
正确获取 query string 的三种方式
根据参数数量、类型和是否需要校验,选不同方法:
-
ctx.URL().Query().Get("name"):原始方式,返回string,适合单值、无默认、不校验场景 -
ctx.FormValue("age"):自动兼容GET查询参数和POST表单,但会忽略重复 key(如?tag=a&tag=b只取第一个) -
ctx.Request().URL.Query()["tags"]:拿到[]string切片,适合多值参数(如标签数组、复选框)
注意:ctx.FormValue() 在纯 GET 请求里能用,但如果接口同时支持 POST 表单和 GET 查询,它会优先读 body,没 body 才 fallback 到 query —— 这个行为容易误判,建议明确用 ctx.URL().Query().Get() 更可控。
类型转换和默认值要自己兜底
Iris 不自动做 query 参数的类型转换或提供默认值,ctx.URL().Query().Get("limit") 永远返回 string,哪怕你期望是 int。常见错误是直接传给 strconv.Atoi() 却没检查 error,导致 panic。
推荐写法:
limitStr := ctx.URL().Query().Get("limit")
if limitStr == "" {
limitStr = "10" // 默认值
}
limit, err := strconv.Atoi(limitStr)
if err != nil {
ctx.StatusCode(400)
ctx.JSON(map[string]string{"error": "invalid limit"})
return
}
别依赖框架“智能推断”,query 参数本质就是字符串键值对,类型和合法性必须由你显式处理。
中文参数、特殊字符要留意编码
如果前端传了 ?q=北京&sort=price%2Bdesc,ctx.URL().Query().Get("q") 返回的是已解码后的 北京,而 ctx.URL().Query().Get("sort") 是 price+desc(%2B → +)。这没问题,但如果你手动拼 URL 或调试时用 curl,得确保发送的是 UTF-8 编码且已正确 percent-encode,否则服务端收到乱码或空值。
容易被忽略的一点:Iris 默认不校验 query 字符串长度或 key 数量,恶意请求如 ?a=1&b=2&c=3&...&z=26(上千个参数)可能拖慢解析,生产环境建议加中间件限制 ctx.Request().URL.RawQuery 长度。











