自定义React应用部署至Heroku时Fetch静态JSON文件报错
问题根因
本地开发环境下,React调试服务会默认做静态资源路径映射,因此存放在项目内的JSON文件可正常被fetch请求到;部署到Heroku后服务由你自行编写的Express程序提供,出现资源请求失败本质是两个原因:
- 静态JSON文件存放位置错误,被构建工具打包进JS bundle,没有作为独立静态文件保留在部署产物中
- Express服务未正确配置静态资源目录的绝对路径映射,请求无法命中对应文件
修复步骤
- 调整静态资源存放位置
在项目根目录(与package.json、Express服务入口文件同级)创建public文件夹,将需要通过fetch请求的静态JSON文件直接放入该目录,禁止将这类需要独立访问的静态资源放在src目录下——src目录下的所有文件会被webpack/babel编译整合进JS打包产物,不会作为独立文件对外提供访问。 - 修正Express静态服务配置
不要使用相对路径配置静态资源目录,Heroku运行时工作目录与本地存在差异,相对路径会导致资源定位失败。替换原有静态配置为以下代码:
如果你给静态资源挂载了自定义路径前缀,前端请求时必须同步加上对应前缀,否则会报404。const express = require('express'); const path = require('path'); const app = express(); // 挂载静态资源目录,使用绝对路径定位根目录下的public文件夹 app.use(express.static(path.join(__dirname, 'public'))); // 配置React单页应用路由兜底,避免页面刷新404 app.get('*', (req, res) => { res.sendFile(path.join(__dirname, 'public', 'index.html')); }); // 监听Heroku自动分配的端口,不要硬写端口号 const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`Service running on port ${PORT}`); }); - 修正前端fetch请求路径
不要在fetch中写本地开发时的相对路径(比如../xxx.json、./src/xxx.json),直接从站点根路径请求资源即可,示例:// 假设JSON文件存放在public/data.json,直接请求根路径下的对应文件 fetch('/data.json') .then(response => response.json()) .then(resData => { // 处理拿到的JSON数据 }) - 校验部署配置
检查项目根目录下的.gitignore文件,确保public目录、你存放的JSON文件没有被忽略,否则Heroku部署时不会上传这部分文件;同时检查package.json中的构建脚本,确保React构建完成后,产物(index.html、打包后的JS/CSS文件)会输出到根目录的public文件夹中,且构建流程不会误删你提前存放在public下的JSON文件。
验证方式
部署完成后,直接在浏览器访问你的Heroku应用域名/[你的JSON文件名],如果可以直接看到完整的JSON内容,说明静态资源配置生效,前端fetch请求即可正常获取数据。
内容的提问来源于stack exchange,提问作者Joe Consterdine
相关产品推荐
相关产品推荐

