Next.js getStaticProps获取WordPress文章失败问题求助
Next.js getStaticProps 从WordPress获取文章失败的解决方案
问题现象
- 客户端渲染时WordPress API端点正常返回数据,但使用
getStaticProps获取文章时失败 - 原始代码报
TypeError: fetch failed;添加try/catch后出现序列化错误:Error serializing.datareturned fromgetStaticPropsin "/posts",提示undefined无法序列化为JSON;将data设为null后无错误但页面一直显示加载中 - 改用axios调用时出现
Error: connect ECONNREFUSED ::1:10052 - 此前用相同逻辑获取WordPress页面完全正常
问题代码
import { wpPosts } from "@/urls/indext"; import { Key } from "react"; const Blog = ({ data }: { data: any }) => { if (!data) { return <h1>Loading...</h1>; } return ( <div> {data.map( (post: { id: Key | null | undefined; title: { rendered: string; }; excerpt: { rendered: string }; slug: string; }) => ( <div key={post.id}> <h2>{post.title.rendered}</h2> <div dangerouslySetInnerHTML={{ __html: post.excerpt.rendered }} /> <a href={`/posts/${post.slug}`}>Read more</a> </div> ) )} </div> ); }; export default Blog; export async function getStaticProps() { const res = await fetch(wpPosts); const data = await res.json(); return { props: { data, }, }; }
解决方案
1. 排查服务器端API可访问性
getStaticProps在构建阶段或服务器端运行,和客户端网络环境不同:
- 本地开发时,若WordPress部署在Docker容器内,不要用
localhost:10052,改用容器IP、服务名(如docker-compose中的服务名称)或局域网IP - 远程部署时,确认服务器防火墙/安全组已开放WordPress API的端口,且域名/IP能被服务器正常解析
- 测试方法:在服务器终端执行
curl ${wpPosts},验证是否能返回JSON数据
2. 修复错误处理与序列化问题
修改getStaticProps,确保始终返回可序列化的有效数据,避免undefined:
export async function getStaticProps() { let data = []; // 默认空数组,避免序列化错误 try { const res = await fetch(wpPosts); // 检查HTTP响应状态 if (!res.ok) { throw new Error(`请求失败,状态码:${res.status}`); } data = await res.json(); } catch (error) { console.error("获取文章列表失败:", error); // 可在此添加告警日志或降级逻辑 } return { props: { data, }, }; }
3. 修正URL配置
检查@/urls/indext(注意文件名拼写错误,应为index)中的wpPosts变量:
- 替换
localhost为服务器端可访问的地址,比如127.0.0.1:10052或容器服务名 - 确认端口号10052正确,且WordPress服务正在运行
4. 优化组件加载状态
避免空数据时一直显示加载,改为提示无内容:
const Blog = ({ data }: { data: any[] }) => { if (data.length === 0) { return <h1>暂无文章</h1>; } return ( <div> {data.map( (post: { id: Key | null | undefined; title: { rendered: string }; excerpt: { rendered: string }; slug: string; }) => ( <div key={post.id}> <h2>{post.title.rendered}</h2> <div dangerouslySetInnerHTML={{ __html: post.excerpt.rendered }} /> <a href={`/posts/${post.slug}`}>Read more</a> </div> ) )} </div> ); };
内容的提问来源于stack exchange,提问作者Vladimir
相关产品推荐
相关产品推荐

