You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用HonoJS从GET请求的URL查询参数中获取嵌套对象

在HonoJS中获取URL查询字符串中的嵌套键值对象

当URL查询参数为cursor[pk]=PK_NAME&cursor[sk]=SK_NAME#1728586654826-c2c67760-d28c-4abe-99f8-2286da2fc5b5这种格式时,直接使用Hono的c.req.query('cursor')或zValidator的z.record会得到undefined,无法自动将分散的cursor[pk]、cursor[sk]合并为嵌套对象,以下是两种可行的解决方案:

方案1:手动解析查询参数

在请求处理器中遍历所有查询参数,提取并组装cursor相关的键值对:

app.get(
  '/',
  zValidator(
    'query',
    z.object({
      limit: z.coerce.number().int().positive().default(50),
      order: z.enum(['asc', 'desc']).default('desc'),
    })
  ),
  async (c) => {
    const { limit, order } = c.req.valid('query')
    const cursor = {}
    // 获取所有查询参数(键对应值数组)
    const allQueries = c.req.queries()
    
    Object.keys(allQueries).forEach(key => {
      // 匹配cursor[xxx]格式的键
      const match = key.match(/^cursor\[(\w+)\]$/)
      if (match) {
        const subKey = match[1]
        // 取数组第一个值(单值场景下)
        cursor[subKey] = allQueries[key][0]
      }
    })

    const data = await queryRecords({ cursor, limit, order })
    return c.json({ cursor: data.cursor, records: data.records })
  }
)

方案2:通过Zod预处理器自动合并

利用Zod的preprocess方法,在校验阶段自动从原始查询参数中提取并组装cursor对象:

// 定义cursor的预处理器Schema
const cursorSchema = z.preprocess((_, ctx) => {
  const rawQuery = ctx.data // 获取原始查询参数
  const cursor = {}
  
  Object.keys(rawQuery).forEach(key => {
    const match = key.match(/^cursor\[(\w+)\]$/)
    if (match) {
      const subKey = match[1]
      cursor[subKey] = rawQuery[key][0]
    }
  })
  
  return cursor
}, z.record(z.string(), z.string()).default({}))

app.get(
  '/',
  zValidator(
    'query',
    z.object({
      cursor: cursorSchema,
      limit: z.coerce.number().int().positive().default(50),
      order: z.enum(['asc', 'desc']).default('desc'),
    })
  ),
  async (c) => {
    const { cursor, limit, order } = c.req.valid('query')
    
    const data = await queryRecords({ cursor, limit, order })
    return c.json({ cursor: data.cursor, records: data.records })
  }
)

原因说明

Hono默认的查询参数解析逻辑仅将每个键值对独立存储,不会自动解析key[subkey]这种格式为嵌套对象。因此直接通过c.req.query('cursor')无法获取到值,Zod的z.record也无法识别分散的cursor[pk]、cursor[sk]字段,需要手动处理或通过预处理器合并。

内容的提问来源于stack exchange,提问作者ALFmachine

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 11:33:18