Next.js生成动态Sitemap部署Vercel时遇JSON解析及404错误求助
Next.js动态Sitemap部署Vercel报错「SyntaxError: Unexpected token < in JSON at position 0」解决方法
问题描述
我尝试用Next.js生成动态Sitemap,本地运行一切正常,但部署到Vercel时出现「SyntaxError: Unexpected token < in JSON at position 0」错误。
我的源代码如下:
export default async function sitemap() { const res = await fetch('https://example.com/api/games'); const games = await res.json(); const gameUrls = games.map((game) => ({ url: `http://localhost:3000/Games/${encodeURIComponent(game.title)}`, lastModified: new Date().toISOString(), })); return [...gameUrls]; }
本地运行时将fetch地址改为http://localhost:3000/api/games就正常,但部署后打印响应结果显示状态码为404,响应信息如下:
Response { [Symbol(realm)]: null, [Symbol(state)]: { aborted: false, rangeRequested: false, timingAllowPassed: true, requestIncludesCredentials: true, type: 'default', status: 404, timingInfo: { startTime: 11159.292941000022, redirectStartTime: 0, redirectEndTime: 0, postRedirectStartTime: 11159.292941000022, finalServiceWorkerStartTime: 0, finalNetworkResponseStartTime: 0, finalNetworkRequestStartTime: 0, endTime: 0, encodedBodySize: 0, decodedBodySize: 0, finalConnectionTimingInfo: null }, cacheState: '', statusText: 'Not Found', headersList: HeadersList { cookies: null, [Symbol(headers map)]: [Map], [Symbol(headers map sorted)]: null }, urlList: [ [URL] ], body: { stream: undefined } }, [Symbol(headers)]: HeadersList { cookies: null, [Symbol(headers map)]: Map(15) { 'access-control-allow-origin' => [Object], 'age' => [Object], 'cache-control' => [Object], 'connection' => [Object], 'content-disposition' => [Object], 'content-encoding' => [Object], 'content-type' => [Object], 'date' => [Object], 'etag' => [Object], 'server' => [Object], 'strict-transport-security' => [Object], 'x-matched-path' => [Object], 'x-vercel-cache' => [Object], 'x-vercel-id' => [Object], 'transfer-encoding' => [Object] }, [Symbol(headers map sorted)]: null } }
错误原因分析
- API路径无效:部署后请求
https://example.com/api/games返回404,说明该路径在Vercel环境下不存在,可能是API路由配置错误或域名未正确关联。 - JSON解析失败:404响应返回的是HTML格式的错误页面,而非预期的JSON数据,调用
res.json()时会解析HTML开头的<符号,直接触发语法错误。 - 域名硬编码问题:生成的Sitemap中使用
localhost域名,部署后搜索引擎无法访问生产环境页面,同时也暴露了本地开发路径的不合理性。
解决方案
1. 修正API请求方式
避免硬编码外部域名,优先直接调用内部业务逻辑(更高效且无路径问题),或使用Vercel环境变量获取生产域名:
// 方式1:直接导入API逻辑(推荐) import getGames from '@/lib/getGames'; export default async function sitemap() { const games = await getGames(); const siteUrl = process.env.NODE_ENV === 'production' ? `https://${process.env.VERCEL_URL}` : 'http://localhost:3000'; const gameUrls = games.map((game) => ({ url: `${siteUrl}/Games/${encodeURIComponent(game.title)}`, lastModified: new Date().toISOString(), })); return [...gameUrls]; } // 方式2:用环境变量拼接API路径 export default async function sitemap() { const baseUrl = process.env.NODE_ENV === 'production' ? `https://${process.env.VERCEL_URL}` : 'http://localhost:3000'; const res = await fetch(`${baseUrl}/api/games`); // 先检查响应状态,避免解析错误页面 if (!res.ok) { throw new Error(`API请求失败,状态码:${res.status}`); } const games = await res.json(); const gameUrls = games.map((game) => ({ url: `${baseUrl}/Games/${encodeURIComponent(game.title)}`, lastModified: new Date().toISOString(), })); return [...gameUrls]; }
2. 替换本地域名
生成Sitemap的URL时,统一使用生产环境域名,通过process.env.VERCEL_URL自动获取Vercel分配的域名,或手动配置自定义域名环境变量。
3. 添加错误处理
在解析JSON前先校验响应状态,提前捕获API请求失败的情况,避免后续解析错误。
内容的提问来源于stack exchange,提问作者boketeボケて
相关产品推荐
相关产品推荐

