
本文详解在 React(尤其是 Vite 构建环境)中通过 fetch() 加载本地 JSON 文件的完整方案,涵盖路径配置、public 目录规范、构建行为适配及常见 404/CORS 错误的根源与解决方法。
本文详解在 react(尤其是 vite 构建环境)中通过 fetch() 加载本地 json 文件的完整方案,涵盖路径配置、public 目录规范、构建行为适配及常见 404/cors 错误的根源与解决方法。
在现代前端开发中,直接使用 fetch('./assets/stationData.json') 或 fetch('../assets/stationData.json') 加载本地 JSON 文件失败,是高频痛点。从你提供的文件结构图和错误截图可见:浏览器实际发起请求的 URL 是类似 http://localhost:5173/assets/stationData.json,但该路径返回 404 —— 这并非代码写错,而是构建工具对静态资源的处理逻辑与开发者预期存在偏差。
✅ 正确做法:将 JSON 文件置于 public/ 目录下
Vite(及 Create React App、Webpack DevServer)约定:public/ 目录下的所有文件会原样复制到构建输出根目录(如 dist/)中,且可通过绝对路径直接访问,无需模块导入或打包处理。这是专为“运行时需动态读取、又不希望被编译/哈希/内联”的静态资源(如 JSON 配置、图标、robots.txt)设计的机制。
✅ 正确操作步骤:
- 将
stationData.json移至项目根目录下的public/文件夹中(例如:public/assets/stationData.json); - 在 React 组件中使用 以
/开头的绝对路径(相对于站点根目录)发起请求:
import { useEffect } from 'react';
const ExploreRivers = () => {
useEffect(() => {
// ✅ 正确:路径以 / 开头,对应 public/ 下的子路径
fetch('/assets/stationData.json')
.then((response) => {
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return response.json();
})
.then((data) => {
console.log('Loaded stations:', data); // data 是解析后的数组
})
.catch((err) => {
console.error('Failed to load station data:', err);
});
}, []);
return <div>Exploring rivers...</div>;
};
export default ExploreRivers;? 关键说明:
/assets/stationData.json中的/表示从 Web 服务器根路径开始查找,Vite 开发服务器会自动将public/assets/映射至此路径,生产构建后也保持相同语义。
React Router Code Review下载审查 React Router 代码,确保数据加载、变更、错误处理和导航模式符合规范,适用于 React Router v6.4+ 代码、加载器及其他特性。
立即学习“前端免费学习笔记(深入)”;
⚠️ 为什么相对路径 ../assets/... 会失败?
-
fetch('../assets/stationData.json')的解析基于当前 HTML 页面的 URL 路径,而非源码文件位置; - 在 Vite 中,你的组件通常由
src/下的.tsx文件编写,但最终渲染的 HTML 是index.html(位于public/或由 Vite 自动生成),其 URL 是http://localhost:5173/; - 因此
../assets/...实际尝试请求的是http://localhost:5173/assets/...—— 若assets/不在public/内,则必然 404; - 更重要的是:
src/assets/下的 JSON 不会自动暴露为可被 fetch 访问的 HTTP 资源,它仅在构建时可能被当作模块导入(如import data from '@/assets/stationData.json'),但该方式会在构建时将 JSON 内容硬编码进 JS 包,失去运行时更新能力。
?️ 进阶:自定义 Vite 的静态资源基础路径(可选)
若项目需部署到子路径(如 https://example.com/my-app/),需配置 Vite 的 base 选项(vite.config.ts):
export default defineConfig({
base: '/my-app/', // 所有静态资源路径前缀
// ...
});此时 fetch('/assets/stationData.json') 将请求 https://example.com/my-app/assets/stationData.json,确保前后端路径一致。
? 注意事项与最佳实践
- JSON 格式必须严格合法:禁止尾随逗号、单引号、注释;推荐用 VS Code 安装 “JSON Tools” 插件校验;
-
编码必须为 UTF-8 无 BOM:BOM 字符会导致
Unexpected token解析错误; -
避免
file://协议直接双击打开 HTML:这会触发浏览器 CORS 策略,fetch必然失败;务必使用vite dev或 Live Server 启动 HTTP 服务; -
生产环境验证:运行
npm run build && npm run preview,确认dist/assets/stationData.json存在且可通过http://localhost:4173/assets/stationData.json直接访问; -
替代方案对比:
- ✅
public/ + fetch():适合需运行时更新、体积较大、非敏感配置类 JSON; - ⚠️
import data from './assets/data.json':适合小而固定的数据,构建时内联,无法热更新; - ❌
fs.readFile/ Node.js API:浏览器环境不可用,仅限服务端。
- ✅
遵循以上方案,你的 stationData.json 将稳定、可靠、跨环境地被 React 组件加载,彻底规避路径 404 与协议限制问题。


















