Next.js 12中getInitialProps获取错误query参数问题咨询
问题根源
你遇到的两个案例差异,本质是Next.js在解析不同结构的自定义路由与页面动态路径匹配时的参数处理逻辑不同:
案例一解析逻辑
案例一中,自定义路由是/truyen-hinh-truc-tuyen/:slug,对应页面路径为/truyen-hinh-truc-tuyen/[slug]。
当通过app.render传递req.params时,Next.js会针对嵌套结构的动态路由做歧义判断——因为父路径truyen-hinh-truc-tuyen下可能存在更复杂的多段动态路由(比如/truyen-hinh-truc-tuyen/[slug]/[id]),所以它会默认将匹配到的slug参数包装为数组,以兼容潜在的多参数场景,最终导致ctx.query.slug成为数组形式。
案例二解析逻辑
案例二中,自定义路由是/:slug.html,对应页面路径为/[slug].html。
这种场景下,动态参数slug直接对应URL中.html前缀的单一部分,Next.js能明确识别这是唯一的动态参数,因此直接将其解析为字符串形式,ctx.query.slug自然就是正常的字符串值。
解决方案
方案一:服务器端显式构造query参数
在自定义服务器路由中,手动构造明确的query对象传递给app.render,避免Next.js的自动解析歧义:
server.get('/truyen-hinh-truc-tuyen/:slug', (req, res) => { console.log('req.params', req.params) // {slug: "vtv1"} // 显式构造query,确保slug为字符串 const query = { slug: req.params.slug }; return app.render(req, res, '/truyen-hinh-truc-tuyen/[slug]', query) })
方案二:在getInitialProps中处理参数
如果无法修改服务器端代码,可以在_app.js的getInitialProps里手动将数组形式的slug转为字符串:
MyApp.getInitialProps = async ({ Component, ctx }) => { // 处理数组形式的slug,取第一个元素 const normalizedSlug = Array.isArray(ctx.query.slug) ? ctx.query.slug[0] : ctx.query.slug; console.log('MyApp query slug', normalizedSlug) // 输出 "vtv1" ... return { } }
补充说明
该问题是Next.js 12.x版本中自定义服务器路由解析的细节行为,在Next.js 13+的App Router路由系统中,由于路由架构重构,这类参数解析歧义问题已大幅减少。
内容的提问来源于stack exchange,提问作者Trinh DL

