MERN应用Heroku部署后API调用失败:替换localhost地址方案
解决MERN应用Heroku部署后API请求指向localhost的问题
核心问题
你所有的axios请求硬编码了localhost:8000,生产环境下浏览器会尝试访问用户本地的8000端口(而非Heroku上的后端),所以出现net::ERR_CONNECTION_REFUSED。你本地能正常访问是因为你同时跑了本地后端服务,其他设备没有,所以报错。
分步解决方案
1. 用环境变量区分开发/生产API地址
在前端项目根目录创建两个环境变量文件:
.env.development(开发环境用):REACT_APP_API_URL=http://localhost:8000/api/v1.env.production(生产环境用):REACT_APP_API_URL=/api/v1
注:Create React App要求环境变量必须以
REACT_APP_开头才能被识别
然后把所有硬编码的localhost:8000/api/v1替换为环境变量,比如:
// 原代码 axios.get('http://localhost:8000/api/v1/posts') // 修改后 axios.get(`${process.env.REACT_APP_API_URL}/posts`)
2. 调整后端server.js配置
确保后端在生产环境正确服务前端静态文件,并使用Heroku提供的端口:
const express = require('express'); const path = require('path'); const app = express(); // ... 其他中间件配置(body-parser、数据库连接等) // 生产环境下服务前端静态文件 if (process.env.NODE_ENV === 'production') { // 指向前端build后的静态资源目录 app.use(express.static(path.join(__dirname, 'client/build'))); // 所有非API请求返回前端index.html(处理React路由) app.get('*', (req, res) => { res.sendFile(path.join(__dirname, 'client/build', 'index.html')); }); } // 使用Heroku提供的端口,本地 fallback到8000 const PORT = process.env.PORT || 8000; app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
3. 保留package.json的proxy配置
你当前package.json里的"proxy": "http://localhost:8000"是给Create React App的开发服务器用的,用于开发时转发API请求到本地后端,生产环境不会生效,所以无需修改。
4. 配置Heroku部署脚本
在根目录的package.json中添加build脚本,确保Heroku部署时自动构建前端:
"scripts": { "start": "node server.js", "build": "cd client && npm install && npm run build", "heroku-postbuild": "npm run build" }
验证步骤
- 本地开发:启动后端
npm start,启动前端cd client && npm start,依然能正常请求本地API - 生产环境:重新部署到Heroku后,浏览器的API请求会自动使用相对路径
/api/v1,指向Heroku上的后端服务,其他设备访问时也能正常拉取数据
内容的提问来源于stack exchange,提问作者techmeowt
相关产品推荐
相关产品推荐

