NextJS应用在Vercel部署失败,遇JSON解析错误求助
Next.js Vercel部署SSG页面时JSON解析错误排查与解决
问题描述
我是前端开发新手,首次尝试在Vercel部署我的第一个Next.js应用时,始终遇到JSON解析错误,错误提示Unexpected token T in JSON at position 0,具体信息及相关代码如下:
错误信息
SyntaxError: Unexpected token T in JSON at position 0 at JSON.parse (<anonymous>) at parseJSONFromBytes (node:internal/deps/undici/undici:6662:19) at successSteps (node:internal/deps/undici/undici:6636:27) at node:internal/deps/undici/undici:1236:60 at node:internal/process/task_queues:140:7 at AsyncResource.runInAsyncScope (node:async_hooks:203:9) at AsyncResource.runMicrotask (node:internal/process/task_queues:137:8) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) > Build error occurred Error: Failed to collect page data for /download/[appName] at /vercel/path0/Bulaloi App/next-app/node_modules/next/dist/build/utils.js:1158:15 at process.processTicksAndRejections (node:internal/process/task_queues:95:5) { type: 'Error' } Error: Command "npm run build" exited with 1
相关代码
Download页面(/pages/download/[appName].js)
import DownloadPage from '../../components/DownloadPageComponents/DownloadPage.js' export default function DownloadPagee({ data }) { return <DownloadPage data={data} />; } export async function getStaticProps({ params }) { const { appName } = params; // Fetch data from `/api/download/${appName}` const res = await fetch(`${process.env.NEXT_PUBLIC_URL}/api/download/${appName}`); const data = await res.json(); return { props: { data } }; } export async function getStaticPaths() { // Fetch data from `/api/apps-games/all` const res = await fetch(`${process.env.NEXT_PUBLIC_URL}/api/apps-games/all`); const data = await res.json(); // Map each object's `appName` property to `params` const paths = data.map((obj) => ({ params: { appName: obj.appName }, })); return { paths, fallback: false }; }
.env变量配置
NEXT_PUBLIC_URL="https://bulaloi.vercel.app"
我曾尝试将NEXT_PUBLIC_URL改为http://bulaloi.vercel.app,但错误依旧。刚接触SSG,怀疑问题出在Download页面代码中,求帮助。
问题原因及解决方法
1. 核心问题:构建阶段无法访问线上API
你在getStaticProps和getStaticPaths里直接调用了线上Vercel域名的API,但SSG是在本地或Vercel构建阶段预生成页面,此时你的应用还未部署完成,线上API根本无法访问,返回的不是合法JSON数据(大概率是404/500页面的HTML,开头是T比如<Title>标签的首字母),所以触发JSON解析错误。
2. 正确处理方式
方法一:直接调用后端逻辑(推荐)
不要通过HTTP请求调用API,而是把API路由里的业务逻辑抽成独立函数,在构建时直接执行获取数据:
- 新建工具文件抽离逻辑:
// lib/appData.js // 抽离/api/download/[appName]的业务逻辑 export async function getDownloadData(appName) { // 这里写原来API路由里获取数据的代码(比如查数据库、读取本地文件等) // 示例: // const data = await db.collection('apps').findOne({ name: appName }); return data; } // 抽离/api/apps-games/all的业务逻辑 export async function getAllApps() { // 这里写原来API路由里获取所有应用的代码 // 示例: // const data = await db.collection('apps').find({}, { projection: { appName: 1 } }).toArray(); return data; }
- 在Download页面中直接调用这些函数:
import DownloadPage from '../../components/DownloadPageComponents/DownloadPage.js' import { getDownloadData, getAllApps } from '../../lib/appData.js' export default function DownloadPagee({ data }) { return <DownloadPage data={data} />; } export async function getStaticProps({ params }) { const { appName } = params; const data = await getDownloadData(appName); // 直接调用逻辑函数,无需HTTP请求 return { props: { data } }; } export async function getStaticPaths() { const data = await getAllApps(); // 直接调用逻辑函数 const paths = data.map((obj) => ({ params: { appName: obj.appName }, })); return { paths, fallback: false }; }
方法二:调试时临时使用fallback模式(仅用于排查)
如果暂时无法抽离逻辑,可将getStaticPaths的fallback改为'blocking',让Next.js在用户访问未预生成的路径时动态生成页面(生产环境不推荐,失去SSG优势):
export async function getStaticPaths() { // ...原有代码 return { paths, fallback: 'blocking' }; }
3. 额外检查点
- 确认API路由返回的是合法JSON,没有语法错误或额外的HTML内容
- 检查
getStaticPaths返回的paths是否包含所有合法的appName值,避免构建时尝试生成不存在的路径
内容的提问来源于stack exchange,提问作者Ame Suzuki
相关产品推荐
相关产品推荐

