You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

部署在Heroku的MERN应用无法获取MongoDB数据求助

Heroku部署MERN应用数据获取失败问题排查

本地环境下MERN应用与MongoDB均运行正常,但部署到Heroku后,其他设备访问网页时出现数据错误,报错信息:

Failed to load resource: net:: ERR_Connection_Refused
localhost:8000/api/ads:1

已完成的配置

  • MongoDB Atlas设置通用网络访问为0.0.0.0/0
  • Heroku中配置了环境变量

相关代码与环境变量

server.js代码

const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const path = require('path');
const session = require('express-session');
const dotenv = require('dotenv');
const MongoStore = require('connect-mongo');
const bcrypt = require('bcryptjs');

// set dotenv
dotenv.config();

// import routes
const noticesRoutes = require('./routes/notices.routes');
const authRoutes = require('./routes/auth.routes');

const app = express();

/* MIDDLEWARE */

app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(session({ 
  secret: bcrypt.hashSync('pass', 8), 
  store: MongoStore.create({ mongoUrl: process.env.DB_URL, collection: 'sessions' }), 
  resave: false, 
  saveUninitialized: false,
  cookie: {
    secure: process.env.NODE_ENV == 'production',
  }, 
}))

// access to storage folder
app.use(express.static(path.join(__dirname, '/client/build')));
app.use(express.static(path.join(__dirname, '/public')));
app.use(express.static(path.join(__dirname, '/uploads/')));

// use routes
app.use('/api', noticesRoutes);
app.use('/auth', authRoutes);

// error status
app.use((req, res) => {
  res.status(404).send('404 not found...');
})

// React website
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname + '/client/build/index.html'));
});

/* MONGOOSE */
const NODE_ENV = process.env.NODE_ENV;
let dbUri = '';
const password = process.env.PASSDB;

if(NODE_ENV === 'production') dbUri = 'mongodb+srv://MarcinEden:' + password + '@cluster1.sg1w6lh.mongodb.net/RealEstateBoard?retryWrites=true&w=majority';
else dbUri = 'mongodb+srv://MarcinEden:' + password + '@cluster1.sg1w6lh.mongodb.net/RealEstateBoard?retryWrites=true&w=majority';

mongoose.connect(dbUri, { useNewUrlParser: true, useUnifiedTopology: true });
const db = mongoose.connection;

db.once('open', () => {
  console.log('Successfully connected to the database');
});
db.on('error', err => console.log('Error: ' + err));

/* START SERVER */
const port = process.env.PORT || 8000;
app.listen(port, () => {
  console.log('Server is running on port: '+ port);
});

.env文件环境变量

NODE_ENV = production
DB_URL = mongodb+srv://MarcinEden:pass@cluster1.sg1w6lh.mongodb.net/RealEstateBoard?retryWrites=true&w=majority

解决思路

  1. 修正前端API请求地址
    报错显示请求指向localhost:8000/api/ads,说明前端硬编码了本地地址。生产环境需改为动态地址:

    • 开发环境用http://localhost:8000
    • 生产环境用相对路径(或空字符串),让请求自动指向Heroku应用域名
  2. 补全缺失的环境变量
    server.js中用到了process.env.PASSDB,但当前.env和Heroku配置中未设置该变量,需在Heroku控制台添加PASSDB变量,值为MongoDB Atlas的数据库密码

  3. 优化MongoDB连接逻辑
    代码中同时存在DB_URL环境变量和手动拼接连接字符串的逻辑,冗余且易出错。建议直接使用process.env.DB_URL作为连接地址:

    mongoose.connect(process.env.DB_URL, { useNewUrlParser: true, useUnifiedTopology: true });
    
  4. 验证Heroku环境变量生效状态
    在终端执行heroku config,确认NODE_ENV、DB_URL、PASSDB三个变量均已正确配置

  5. 调整CORS配置(可选)
    生产环境可限定CORS origin为Heroku应用域名,避免跨域问题:

    app.use(cors({
      origin: process.env.NODE_ENV === 'production' ? 'https://你的Heroku应用域名.herokuapp.com' : 'http://localhost:3000',
      credentials: true
    }))
    

内容的提问来源于stack exchange,提问作者MarcinB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 19:40:06