Next.js动态路由中Urql获取Slug时出现GraphQL 400错误
问题描述
我正在开发一个前端基于Next.js和GraphQL、后端集成Stripe的电商应用,使用Urql进行数据获取。在Frontend/pages/product/[slug].js文件中,我通过useRouter()从URL获取slug,并将其作为变量传入useQuery()的GET_PRODUCT_QUERY,但运行后控制台报错:tp://localhost:1337/graphql 400 (Bad Request)。
相关代码
slug.js
import { useQuery } from "urql" import { GET_PRODUCT_QUERY } from "@/lib/query" import { useRouter } from "next/router" /* eslint-disable @next/next/no-img-element */ export default function ProductDetails() { // 获取Slug const { query } = useRouter() // 获取GraphQL数据 const [results] = useQuery({ query: GET_PRODUCT_QUERY, variables: { slug: query.slug }, }) const { data, fetching, error } = results // 检查数据状态 if (fetching) return <p>Loading...</p> if (error) return <p>Oh No.....{error.message}</p> return ( <div> <img src="" alt="" /> <div> <h3>Title</h3> <p>description</p> </div> <div> <span>Quantity</span> <button>Plus</button> <p>0</p> <button>Minus</button> </div> <button>Add to cart</button> </div> ) }
query.js
export const PRODUCT_QUERY = ` query { products { data { attributes { title description price slug image { data { attributes { formats } } } } } } } ` export const GET_PRODUCT_QUERY = ` query getProduct($slug: String!) { products(filters: {slug: {eq: $slug}}) { data { attributes { title slug description price image { data { attributes { formats } } } } } } } `
错误信息
控制台返回:tp://localhost:1337/graphql 400 (Bad Request)
解决方案
400 Bad Request属于GraphQL请求格式或参数错误,结合你的代码,可从以下几个方向排查修复:
- 处理Slug未初始化的情况
Next.js的useRouter()在页面首次加载时,query.slug可能为undefined,但你的GraphQL查询声明$slug是必填的String!,空值会直接导致请求失败。
修复方式:给查询添加暂停逻辑,或提前判断slug是否存在:
// 方式1:暂停查询直到slug存在 const [results] = useQuery({ query: GET_PRODUCT_QUERY, variables: { slug: query.slug }, pause: !query.slug, }) // 方式2:提前拦截无效请求 if (!query.slug) return <p>无效的产品链接</p>
- 修复GraphQL端点URL错误
错误信息中的URL缺失http前缀(显示为tp://),这会导致请求地址无效。检查Urql客户端的配置,确保端点是完整的合法URL:
// 在_app.js或客户端配置文件中 const client = createClient({ url: 'http://localhost:1337/graphql', // 必须是完整的http/https开头的地址 });
- 修正Strapi过滤器语法
如果你的后端是Strapi,过滤器需要使用$eq而非eq(部分版本要求严格遵循GraphQL规范),修改查询语句:
export const GET_PRODUCT_QUERY = ` query getProduct($slug: String!) { products(filters: {slug: { $eq: $slug }}) { data { attributes { title slug description price image { data { attributes { formats } } } } } } } `
- 验证Urql客户端配置
确保Urql客户端已正确挂载到Next.js应用中,比如在_app.js中配置Provider:
import { Provider, createClient } from 'urql'; const client = createClient({ url: 'http://localhost:1337/graphql', }); function MyApp({ Component, pageProps }) { return ( <Provider value={client}> <Component {...pageProps} /> </Provider> ); } export default MyApp;
内容的提问来源于stack exchange,提问作者GYANIROMAN23
相关产品推荐
相关产品推荐

