Next.js向GraphQL传slug参数触发Syntax Error报错排查
问题根因
核心错误是用JavaScript模板字符串插值的方式,直接把动态slug值拼接进GraphQL查询语句,没有正确使用GraphQL的变量传参机制。
- 你虽然在查询头部声明了
$slug: String!的变量类型,但实际查询条件里没有引用这个变量,而是直接插入裸的slug值,最终生成的查询片段会变成where:{slug:your-slug-value}的形式。 - GraphQL解析器遇到没有引号包裹、也不是数字/布尔/枚举的裸字符串时,会先尝试按数字类型解析,碰到slug开头的字母(比如报错里提到的"t")就会抛出
Invalid number, expected digit but got: "t"语法错误。 - 硬编码能正常请求是因为你写死值的时候大概率手动给字符串加了双引号,符合GraphQL的语法要求,但动态拼接时没有做引号包裹和转义,不仅会触发语法错误,还存在GraphQL注入、特殊字符转义失败的风险。
修复方案
不要在gql模板标签内做动态值拼接,统一通过Apollo客户端的variables字段传递动态参数:
- 先把查询语句改成固定结构,where条件直接引用预先声明的
$slug变量,不需要再给查询函数传参做拼接:
const GET_SLUG_QUERY = gql` query ($slug: String!) { postCollection(where: { slug: $slug }) { items { title shortDescription heroImg { url } createdAt slug } } } `;
- 修改getStaticProps中的查询调用,把slug值放到variables配置项中传入:
export const getStaticProps = async (context) => { const apolloClient = initializeApollo(); const { data } = await apolloClient.query({ query: GET_SLUG_QUERY, variables: { slug: context.params.id } }); // 保留原有后续逻辑
注意:不要为了省事给拼接的slug手动加引号凑语法,这种写法无法处理slug中带引号、特殊符号的场景,也存在安全风险,GraphQL官方明确要求动态参数必须通过variables机制传递。
你提供的getStaticPaths逻辑没有问题,不需要修改。
内容的提问来源于stack exchange,提问作者Roberto Fosso
相关产品推荐
相关产品推荐

