Next.js+Sanity部署Vercel报错:JSON响应无效(Unexpected token T)
解决方案
1. 修复fetchExperiences函数的变量名错误
你的fetchExperiences函数存在明显笔误:定义了projects变量,但返回的是未声明的experience,这会触发运行时错误,导致API返回非JSON格式的错误文本(比如以"TypeError"开头,对应报错里的Unexpected token T)。
修改后代码:
import {Experience} from '../typings' export const fetchExperiences = async () =>{ const res = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/getExperience`) // 先校验响应状态,提前拦截错误 if (!res.ok) { throw new Error(`API请求失败: ${res.status}`) } const data = await res.json() const experiences:Experience[] = data.experience return experiences }
2. 简化API路由的JSON返回逻辑
getExperience.ts里的JSON.parse(JSON.stringify({experience}))完全多余,Next.js的res.json()会自动处理对象序列化,多余的序列化/反序列化可能引发意外问题。同时添加错误捕获,避免返回非JSON内容:
修改后代码:
import type{NextApiRequest,NextApiResponse} from 'next' import {groq} from 'next-sanity'; import {sanityClient} from '../../sanity'; import {Experience} from '../../typings' const query = groq` *[_type == "experience"]{ ..., technologies[]-> } `; type Data ={ experience:Experience[] } export default async function handler( req:NextApiRequest, res:NextApiResponse<Data>, ){ try { const experience:Experience[]= await sanityClient.fetch(query) res.status(200).json({experience}) } catch (err) { // 捕获错误并返回合法JSON res.status(500).json({ experience: [], error: '获取数据失败' }) } }
3. 优化getStaticProps的数据源获取(可选但推荐)
在getStaticProps中无需通过HTTP请求调用自身API,直接在服务端调用Sanity查询逻辑即可,既能避免环境变量配置问题,还能提升构建效率:
修改index.ts的getStaticProps:
import { groq } from 'next-sanity'; import { sanityClient } from '../sanity'; import { Experience, Skill, Project, Social } from '../typings'; // 单独提取各数据的GROQ查询 const experienceQuery = groq` *[_type == "experience"]{ ..., technologies[]-> } `; const skillQuery = groq`/* 替换为你的技能查询语句 */`; const projectQuery = groq`/* 替换为你的项目查询语句 */`; const socialQuery = groq`/* 替换为你的社交链接查询语句 */`; export const getStaticProps: GetStaticProps<Props> = async() => { try { const experience : Experience[] = await sanityClient.fetch(experienceQuery); const skills : Skill[] = await sanityClient.fetch(skillQuery); const projects : Project[] = await sanityClient.fetch(projectQuery); const socials : Social[] = await sanityClient.fetch(socialQuery); return{ props:{ experience, skills, projects, socials, }, revalidate:10 } } catch (err) { console.error('构建时获取数据失败:', err); // 返回默认空数据避免构建失败 return{ props:{ experience: [], skills: [], projects: [], socials: [], }, revalidate:10 } } }
4. 验证环境变量配置
确保Vercel后台的NEXT_PUBLIC_BASE_URL已正确设置为你的部署域名(比如https://portfolio2-1-wn3v.vercel.app),并重新部署使配置生效。
排查思路总结
Unexpected token T这类报错通常说明API返回的不是合法JSON,而是文本格式的错误信息(比如"TypeError: experience is not defined"),优先排查:
- 代码中的变量名错误、未捕获的异常
- API路由是否有完善的错误捕获逻辑
- 部署日志中的具体错误栈信息
内容的提问来源于stack exchange,提问作者Nejc Lampič
相关产品推荐
相关产品推荐

