c.query()是最常用方式,专用于获取url查询参数单个字符串值,不自动转类型;c.queries()则返回全部同名参数的字符串切片映射;c.params()仅处理路径参数,对query无效。

用 c.Query() 取单个字符串参数
这是最常用、最直接的方式。Fiber 的 c.Query() 专为 URL 查询参数(即 ?key=value 部分)设计,返回 string 类型,不自动转类型。
常见错误现象:调用 c.Params("key") 却拿不到值——因为 c.Params 只处理路径参数(如 /users/:id 中的 :id),对 query 完全无效。
-
c.Query("page"):无值时返回空字符串"" -
c.Query("page", "1"):提供默认值,参数缺失或为空时返回"1" - 想转成整数?必须手动:
page, _ := strconv.Atoi(c.Query("page", "1"));别依赖框架自动转换 - 注意:即使 URL 是
/list?page=1&page=2,c.Query("page")也只取第一个值("1"),重复键需用c.Queries()
用 c.Queries() 拿全部查询参数(map[string][]string)
当 URL 含多个同名参数(如 ?tag=go&tag=fiber&tag=web),或你想一次性检查所有 query 键时,c.Queries() 返回的是 map[string][]string,保留全部原始值。
使用场景:过滤标签、多选搜索条件、调试请求参数完整性。
-
params := c.Queries()→ 得到完整映射,params["tag"]是[]string{"go", "fiber", "web"} - 它不会合并或去重,原样反映客户端传入的顺序和数量
- 和
c.Query("tag")不冲突:前者取全部,后者只取首个 - 如果只是要转成普通 map[string]string(丢弃重复值),可遍历
params取每个 slice 的[0],但需自行判空
别误用 c.Params() 或 c.Body() 去读 query
c.Params() 和 c.Body() 完全不处理查询字符串。混淆它们是新手高频坑。
容易踩的坑:
- URL 是
/api/user?id=123,却写c.Params("id")→ 返回空字符串,不是"123" - 把 JSON POST 请求体里的字段名,和 query 参数名搞混,结果在 GET 接口里调
c.Body()→ 返回空或 panic -
c.Headers、c.Cookies()同理:各自数据源隔离,不能越界访问 - 调试时建议打印
c.Request().URI().String()确认原始 URL,再决定用哪个方法
生产环境慎用 query 传密钥或敏感标识
虽然 c.Query("token") 能拿到值,但 query 参数会明文出现在访问日志、代理记录、浏览器历史、CDN 缓存中。
例如用 fiber.KeyAuth(fiber.KeyAuthConfig{Extractor: keyauth.FromQuery("key")}) 做校验,仅适合本地调试。
- 正式接口必须改用
keyauth.FromHeader("X-API-Key")或keyauth.FromForm("key") - 如果前端必须走 query(如某些第三方回调),至少加一次签名验证,且 key 本身应为短期有效的一次性令牌
- 日志中间件里记得过滤掉
key、token、secret等关键词,避免泄露
?filter[name]=john&filter[age]=30),这种需求得自己 parse URI.RawQuery 或换用更上层的库。











