在Next.js中调用无头WordPress GraphQL接口时posts返回undefined
问题:Next.js调用GraphQL接口获取posts返回undefined,但Playground可正常运行
我的GraphQL查询在本地GraphQL Playground中能正常返回数据,但在Next.js项目里调用接口时,posts始终返回undefined——页面能显示h1标题,但文章列表加载不出来。我的代码如下:
import Link from 'next/link' export default function Home( {posts}){ console.log({posts}) return( <div> <h1>Hello From The Home Page!</h1> { posts?.nodes?.map(post => { return( <ul key={post.slug}> <li> <Link href={`/posts/${post.slug}`}>{post.title}</Link> </li> </ul> ) }) } </div> ) } export async function getInitialProps(){ const res = await fetch('http://trialtest1.local/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: ` query HomePageQuery { posts { nodes { slug title } } } `, }) }) const json = await res.json() return { props: { posts: json.data.posts, }, } }
排查与修复方案
1. 先加错误捕获,明确请求问题
你的代码未处理请求失败场景,一旦接口请求出错(跨域、状态码非200等),json.data就会是undefined。先在getInitialProps中添加错误捕获和日志打印,定位问题:
export async function getInitialProps(){ try { const res = await fetch('http://trialtest1.local/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: ` query HomePageQuery { posts { nodes { slug title } } } `, }) }) // 检查请求是否成功 if (!res.ok) { console.error('请求失败:', res.status, res.statusText) return { props: { posts: null } } } const json = await res.json() console.log('接口完整返回:', json) // 打印全量返回结果,排查是否有data/errors字段 // 检查GraphQL自身错误 if (json.errors) { console.error('GraphQL查询错误:', json.errors) return { props: { posts: null } } } return { props: { posts: json.data?.posts || null, }, } } catch (err) { console.error('网络/请求错误:', err) return { props: { posts: null } } } }
运行后查看控制台日志,就能明确是请求失败、GraphQL语法错误还是返回结构异常。
2. 最可能的原因:跨域问题
本地Next.js开发服务(通常是http://localhost:3000)和GraphQL服务(http://trialtest1.local)属于不同域名,浏览器会拦截跨域请求,导致fetch失败。有两种解决方式:
方法一:在GraphQL服务端开启CORS
如果是WordPress的WPGraphQL,直接安装启用WPGraphQL CORS插件,配置允许http://localhost:3000的跨域请求;其他服务则在后端添加响应头Access-Control-Allow-Origin,值为你的Next.js域名。
方法二:用Next.js API路由做代理
在项目中创建pages/api/graphql-proxy.js文件:
export default async function handler(req, res) { const { body, method } = req; try { const graphqlRes = await fetch('http://trialtest1.local/graphql', { method, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), }); const data = await graphqlRes.json(); res.status(graphqlRes.status).json(data); } catch (err) { res.status(500).json({ errors: [{ message: '代理请求失败' }] }); } }
然后修改getInitialProps中的请求地址为代理接口:
const res = await fetch('/api/graphql-proxy', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: `query HomePageQuery { posts { nodes { slug title } } }` }) })
3. 确保查询语句完全一致
有时POST请求中的查询存在多余换行或空格,可能导致服务端解析异常。直接复制Playground中可运行的查询字符串,精简格式:
query: `query HomePageQuery { posts { nodes { slug title } } }`
内容的提问来源于stack exchange,提问作者gritoverflow
相关产品推荐
相关产品推荐

