React按钮点击触发Invalid JSON错误的问题求助
问题排查与解决思路
这个错误的核心是:前端请求后端接口时,收到的不是预期的JSON数据,而是HTML内容(比如404页面、前端的index.html),导致JSON解析失败。下面是具体排查点:
1. 核对前端请求URL是否正确
- 确认前端fetch/axios的请求地址和后端接口完全匹配。如果后端运行在3001端口、前端在3000端口,直接写
fetch('/api/private')会请求前端自己的3000端口,返回index.html,必须指定后端地址fetch('http://localhost:3001/api/private'),或者在前端package.json中配置"proxy": "http://localhost:3001"后再用相对路径请求。 - 错误示例:
// 未指定后端端口,请求指向前端服务 fetch('/api/private') - 正确写法(二选一):
// 直接指定后端地址 fetch('http://localhost:3001/api/private') // 配置proxy后用相对路径 fetch('/api/private')
2. 检查后端路由配置顺序
- 确保API路由的挂载顺序在静态文件和兜底路由之前。如果先挂载
express.static或兜底的*路由,API请求会被优先匹配到静态文件或前端页面,返回HTML。 - 错误示例:
// 先处理静态文件,再处理API路由,导致API请求被拦截 app.use(express.static(path.join(__dirname, 'build'))); app.use('/api', require('./routes/api')); app.get('*', (req, res) => res.sendFile(path.join(__dirname, 'build', 'index.html'))); - 正确顺序:
// 先处理API路由 app.use('/api', require('./routes/api')); // 再处理静态文件和SPA兜底路由 app.use(express.static(path.join(__dirname, 'build'))); app.get('*', (req, res) => res.sendFile(path.join(__dirname, 'build', 'index.html')));
3. 确认后端接口返回JSON格式
- 后端必须用
res.json()返回数据,不能用res.send()返回纯文本。纯文本会被前端当成JSON解析,触发语法错误。 - 错误示例:
// 返回纯文本,前端解析JSON失败 app.get('/api/private', (req, res) => { res.send('private'); }); - 正确写法:
app.get('/api/private', async (req, res) => { // 业务逻辑... res.json({ message: 'private' }); // 返回JSON对象 });
4. 排查跨域(CORS)问题
- 前后端端口不同时,后端必须配置CORS,否则浏览器会拦截请求,返回的可能是跨域错误页面(HTML)。安装并启用cors中间件:
npm install corsconst cors = require('cors'); app.use(cors()); // 生产环境建议配置具体允许的域名
5. 捕获后端接口错误并返回JSON
- 如果后端接口因MongoDB连接失败等原因抛出错误,未正确捕获的话会返回默认的HTML错误页面。必须在接口中添加错误捕获,返回JSON格式的错误信息:
app.get('/api/private', async (req, res) => { try { // 数据库查询逻辑 const data = await YourModel.findOne({ ... }); res.json({ message: 'private' }); } catch (err) { res.status(500).json({ error: err.message }); // 返回JSON格式错误 } });
内容的提问来源于stack exchange,提问作者M3VRIX
相关产品推荐
相关产品推荐

