MERN应用开发环境API返回JSON,生产环境返回HTML致调用失败求助
解决MERN应用生产环境API调用返回HTML的问题
嘿,这个问题我之前也碰到过!你看到的SyntaxError: Unexpected token < in JSON at position 0错误,本质是因为你的前端API请求拿到的不是预期的JSON数据,而是前端的index.html页面——这正好和Postman测试的结果对应上了:Heroku上的/api/check请求被引导到了静态页面,根本没触发API逻辑。
问题根源
在生产环境的服务器配置里,你的API路由被静态文件的 fallback 规则覆盖了。简单说:服务器接收到请求后,优先匹配到了返回index.html的规则,完全没走到你的API路由处理逻辑里。
修复步骤
你需要调整server.js里的代码顺序,必须先定义API路由,再配置静态文件服务和SPA fallback路由,具体如下:
先配置基础中间件
先设置Express的必要中间件,比如解析JSON、处理跨域这些:const express = require('express'); const path = require('path'); const app = express(); // 基础中间件配置 app.use(express.json()); app.use(express.urlencoded({ extended: true })); // 如果需要跨域支持,引入并配置cors const cors = require('cors'); app.use(cors());接着定义所有API路由
把你的API路由放在静态文件配置之前,确保请求能先命中API规则:// 示例:如果拆分了路由文件,先导入再挂载 const checkRouter = require('./routes/check'); app.use('/api/check', checkRouter); // 或者直接写API处理逻辑 app.get('/api/check', (req, res) => { res.json({ status: 'success', message: 'API正常运行' }); });然后配置静态文件服务
指向前端build后的文件夹:// 提供前端静态文件服务 app.use(express.static(path.join(__dirname, 'build')));最后添加SPA Fallback路由
这个路由要放在最末尾,用来处理所有非API的请求,返回index.html以支持SPA路由:// 所有非API请求返回index.html,适配SPA路由 app.get('*', (req, res) => { res.sendFile(path.join(__dirname, 'build', 'index.html')); });
额外检查项
- 确认
package.json里有正确的Heroku构建命令,比如:"scripts": { "start": "node server.js", "build": "cd client && npm install && npm run build", "heroku-postbuild": "npm run build" } - 检查Heroku上的环境变量(比如数据库连接字符串)是否配置正确,避免API内部报错导致意外返回HTML(不过你的情况更大概率是路由顺序问题)。
修复后重新部署到Heroku,再用Postman测试https://desolate-brushlands-16337.herokuapp.com/api/check,应该就能拿到预期的JSON数据了,前端的API调用也不会再报错啦!
内容的提问来源于stack exchange,提问作者myrrtle
相关产品推荐
相关产品推荐

