单页应用请求Fake JSON报错:Unexpected token < in JSON at position 0
问题分析
你碰到的Unexpected token < in JSON at position 0错误,核心原因是浏览器请求/api/characters时,拿到的不是预期的JSON数据,而是React项目的index.html页面——JSON解析器遇到HTML开头的<符号自然会报错。Postman能正常获取数据,说明后端API本身是可用的,但浏览器的请求没有被正确路由到后端。
可能的原因及解决方案
1. 后端文件路径笔误(最常见)
看你的文件结构,fakeData.json在route文件夹下,但movieList.js里却在读取characters.json:
// 错误路径:你的JSON文件是fakeData.json,不是characters.json fs.readFileSync(__dirname+'/characters.json', 'utf8') const characters = require('../FakeData/characters.json');
修复方式:
把路径修正为正确的fakeData.json:
// 同步读取写法 const characters = require('./fakeData.json'); // fs读取写法 const fileContents = fs.readFileSync(__dirname+'/fakeData.json', 'utf8')
如果你的JSON文件实际叫characters.json,忽略这一步,但要确保文件确实存在于route目录下。
2. 开发环境代理配置问题
你使用的http-proxy-middleware可能存在版本兼容或匹配规则问题:
- 新版
http-proxy-middleware需要使用createProxyMiddleware导出项 - 路径匹配
/api/*的规则不够精准,建议直接匹配/api前缀
修复代理配置:
const { createProxyMiddleware } = require('http-proxy-middleware'); module.exports = function(app) { app.use('/api', createProxyMiddleware({ target: 'http://localhost:5000', changeOrigin: true })); };
修改后重启前端开发服务器,确保请求能正确转发到后端5000端口。
3. 生产环境路由 fallback 逻辑优化
你的index.js中生产环境的路由仅处理根路径/,如果是其他前端路由需要返回index.html,但要避免API请求被误导向HTML。可以优化路由规则:
if (process.env.NODE_ENV === 'production') { app.use(express.static('client/build')); const path = require('path'); // 匹配所有非API路径,返回index.html app.get('*', (req, res) => { if (!req.path.startsWith('/api')) { res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html')); } }); }
这样能确保/api开头的请求优先被后端API处理。
4. 前端调试建议
暂时把res.json()改成res.text(),打印返回内容确认是不是HTML:
export function fetchChars() { return dispatch => { fetch('/api/characters') .then(res => res.text()) .then(text => { console.log('Response content:', text); // 查看是否是HTML return JSON.parse(text); }) .then(data => dispatch(setMovies(data.characters))) .catch(err => console.error('Fetch error:', err)); } }
如果打印结果是HTML,说明请求没到达后端,回到代理或路由配置排查。
额外检查点
- 确保后端服务器(5000端口)和前端开发服务器(3000端口)同时启动
- 查看浏览器Network面板的请求URL,确认是
http://localhost:3000/api/characters(开发环境下应通过代理转发) - 在
index.js中添加日志,确认后端路由已成功注册:
const movieRoutes = require('./routes/movieList'); console.log('Registering movie API routes'); movieRoutes(app);
内容的提问来源于stack exchange,提问作者Johnny88520




