Next.js 13.3读取public文件夹JSON文件报错:无法解析URL /data.json
问题原因
你的异步组件是Server Component(Next.js App Router默认行为),在服务器端执行fetch('/data.json')时,Node.js环境的fetch API不支持相对路径——浏览器会自动补全当前页面的域名和协议,但服务器端没有这个上下文,因此会抛出Failed to parse URL from /data.json错误。
解决方法
提供三种针对性方案,按需选择:
方案1:服务器端直接读取文件(推荐)
public文件夹的内容在服务器端可直接通过文件系统访问,无需HTTP请求,性能更优:
import fs from 'fs/promises'; import path from 'path'; async function getData() { try { // 拼接public目录下data.json的绝对路径 const filePath = path.join(process.cwd(), 'public', 'data.json'); const fileContent = await fs.readFile(filePath, 'utf-8'); return JSON.parse(fileContent); } catch (e) { console.error(e.message); return null; } }
方案2:补全完整URL
若必须使用fetch,需在服务器端补全包含协议、域名的完整URL:
方式A:通过请求头自动获取当前域名
import { headers } from 'next/headers'; async function getData() { try { const headersList = headers(); const protocol = headersList.get('x-forwarded-proto') || 'http'; const host = headersList.get('host'); const res = await fetch(`${protocol}://${host}/data.json`); return await res.json(); } catch (e) { console.error(e.message); return null; } }
方式B:使用环境变量固定域名
在项目根目录的.env.local文件中添加:
NEXT_PUBLIC_APP_URL=http://localhost:3000
修改getData函数:
async function getData() { try { const res = await fetch(`${process.env.NEXT_PUBLIC_APP_URL}/data.json`); return await res.json(); } catch (e) { console.error(e.message); return null; } }
方案3:转为客户端组件
若组件无需服务器端渲染,添加'use client'指令,让fetch在浏览器环境执行(浏览器会自动补全相对路径):
'use client'; export default async function NotesPage() { const data = await getData(); return ( // 你的组件内容 ); }
内容的提问来源于stack exchange,提问作者DJ Asuncion
相关产品推荐
相关产品推荐

