React/Node项目部署Replit/Heroku后页面空白问题求助
问题描述
我正在开发基于React和NodeJS/Express的电商服务,部署到Replit后仅本地服务器能正常运行,其他设备打开页面显示空白。推测是服务器配置存在问题,已查阅StackOverflow相关话题但未找到解决方案,希望获得配置修正的相关建议。
服务器index.js代码
const express = require('express'); const mongoose = require('mongoose'); const dotenv = require('dotenv'); const cors = require('cors'); const session = require('express-session'); const MongoStore = require('connect-mongo'); const path = require('path'); // set dotenv dotenv.config(); // set app const app = express(); app.listen(process.env.PORT || 8000, () => { console.log('Server is running on port 8000', process.env.PORT) }); // mongoDB connection mongoose .connect(process.env.MONGO_URL, { useNewUrlParser: true, useUnifiedTopology: true }) .then(() => {console.log('DB connection succesfull')}) .catch((err) => {console.log('DB error is', err)}); // middleware app.use(cors({ origin: ["http://localhost:3000", "http://localhost:8000"], methods: ['POST', 'PUT', 'GET', 'OPTIONS', 'HEAD', 'DELETE'], credentials: true })) if(process.env.NODE_ENV !== 'production') { app.use( cors({ origin: ['http://localhost:3000'], credentials: true, }) ); } app.use(express.json()); app.use(express.urlencoded({ extended: false})); app.use(session({ secret: process.env.SECRET, store: MongoStore.create(mongoose.connection), resave: false, saveUninitialized: false, /* This cause error in creating user session - no login available cookie: { secure: process.env.NODE_ENV == 'production', },*/ })); // access to storage folder app.use(express.static(path.join(__dirname, '/client/build'))); // import routes const userRoute = require('./routes/user.routes'); const authRoute = require('./routes/auth.routes'); const productRoute = require('./routes/products.routes'); const orderRoute = require('./routes/order.routes'); // use routes app.use('/api', userRoute); app.use('/auth', authRoute); app.use('/products', productRoute); app.use('/orders', orderRoute); app.get('*', (req, res) => { res.sendFile(path.join(__dirname, '/client/build/index.html')); });
.env文件
MONGO_URL = mongodb+srv://user:pass@cluster0.hpidkxl.mongodb.net/prospero?retryWrites=true&w=majority SECRET = pass NODE_ENV = production PASS_SEC = marc
配置文件
export const API_URL = (process.env.NODE_ENV === 'production') ? '/' : 'http://localhost:8000/';
.gitignore文件
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. # dependencies /node_modules /.pnp .pnp.js # testing /coverage # production # misc .DS_Store .env.local .env.development.local .env.test.local .env.production.local npm-debug.log* yarn-debug.log* yarn-error.log*
package.json文件
{ "name": "04-prosperostore", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "nodemon index.js" }, "repository": { "type": "git", "url": "git+https://github.com/MarcinBieniek/ProsperoStore.git" }, "keywords": [], "author": "", "license": "ISC", "bugs": { "url": "https://github.com/MarcinBieniek/ProsperoStore/issues" }, "homepage": "https://github.com/MarcinBieniek/ProsperoStore#readme", "dependencies": { "@mui/x-data-grid": "^6.0.2", "axios": "^1.3.4", "bcryptjs": "^2.4.3", "connect-mongo": "^4.6.0", "cors": "^2.8.5", "crypto-js": "^4.1.1", "dotenv": "^16.0.3", "express": "^4.18.2", "express-session": "^1.17.3", "mongoose": "^7.0.1", "multer": "1.4.4", "nodemon": "^2.0.21", "path": "^0.12.7", "redux-thunk": "^2.4.2" } }
配置修正建议
1. 修复CORS配置问题
当前代码重复调用app.use(cors()),生产环境下仅允许localhost来源,导致外部设备无法访问。调整方案:
- 删除重复的CORS中间件
- 生产环境指定Replit分配的应用域名作为允许来源,可通过环境变量注入
- 修改后的CORS配置示例:
const allowedOrigins = process.env.NODE_ENV === 'production' ? [process.env.REPLIT_APP_URL] // 替换为你的Replit公开域名,如https://xxx.replit.app : ["http://localhost:3000", "http://localhost:8000"]; app.use(cors({ origin: allowedOrigins, methods: ['POST', 'PUT', 'GET', 'OPTIONS', 'HEAD', 'DELETE'], credentials: true }));
注意:在Replit的环境变量面板中添加REPLIT_APP_URL,值为应用的公开访问域名。
2. 调整服务器监听逻辑
将服务器启动逻辑移至MongoDB连接成功后,避免服务启动但数据库未就绪的情况,同时修正端口打印信息:
// 替换原有的数据库连接和服务器启动代码 mongoose.connect(process.env.MONGO_URL, { useNewUrlParser: true, useUnifiedTopology: true }) .then(() => { console.log('DB connection successful'); const PORT = process.env.PORT || 8000; app.listen(PORT, () => { console.log(`Server is running on port ${PORT}`); }); }) .catch((err) => {console.log('DB error is', err)});
3. 静态文件路径验证
确认Replit中client/build目录存在且路径正确,可添加日志打印验证:
const buildPath = path.join(__dirname, '/client/build'); console.log('Static files path:', buildPath); app.use(express.static(buildPath));
4. 修正启动脚本
生产环境使用nodemon不合适,替换为node直接启动,保留dev脚本用于开发:
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "node index.js", "dev": "nodemon index.js" }
5. 完善会话Cookie配置
取消注释Cookie配置,添加sameSite属性适配生产环境HTTPS:
app.use(session({ secret: process.env.SECRET, store: MongoStore.create(mongoose.connection), resave: false, saveUninitialized: false, cookie: { secure: process.env.NODE_ENV === 'production', sameSite: process.env.NODE_ENV === 'production' ? 'none' : 'lax', maxAge: 24 * 60 * 60 * 1000 // 可选,设置Cookie有效期为1天 }, }));
注:sameSite: 'none'必须配合secure: true使用,Replit公开域名默认使用HTTPS,符合要求。
6. 确认环境变量加载
Replit不会自动加载本地.env文件,需在Replit的环境变量面板中手动添加所有.env中的变量(如MONGO_URL、SECRET等)。
内容的提问来源于stack exchange,提问作者MarcinB
相关产品推荐
相关产品推荐

