部署到Heroku的React+Node应用无法读取后端数据停留在登录页求助
问题根因排查及解决方法
核心问题1:前端接口地址硬编码为本地地址
你当前frontend/src/index.js中配置的Apollo请求地址固定为http://localhost:5000/,部署到Heroku后,用户浏览器访问时仍会向本地5000端口发请求,自然无法连通线上后端服务。
修改方案:
替换frontend/src/index.js中createHttpLink部分的代码,根据运行环境动态切换接口地址:
const httpLink = createHttpLink({ uri: process.env.NODE_ENV === 'production' ? '/graphql' // 生产环境和后端同域,走相对路径 : 'http://localhost:5000/graphql' // 本地开发指向本地后端 });
注:Apollo Server默认的GraphQL接口路径为/graphql,请和后端实际配置保持一致
核心问题2:生产环境未配置后端托管前端静态资源
你当前用的apollo-server默认不支持托管静态文件,生产环境前端build生成的静态文件需要后端服务托管才能正常访问,同时要适配React路由的history模式。
修改方案:
- 后端安装
apollo-server-express和express:
进入frontend/backend目录执行:
npm install apollo-server-express express
- 修改
frontend/backend/index.js代码,增加静态资源托管逻辑:
const express = require('express'); const { ApolloServer } = require('apollo-server-express'); const path = require('path'); const mongoose = require('mongoose'); const typeDefs = require('./graphql/typeDefs'); const resolvers = require('./graphql/resolvers'); const MONGODB = process.env.MONGODB; const app = express(); const ports = process.env.PORT || 5000 const server = new ApolloServer({ typeDefs, resolvers, context: ({ req }) => ({ req }) }); // 托管前端build后的静态文件 app.use(express.static(path.join(__dirname, '../../build'))); // 适配React路由history模式,所有非接口请求返回index.html app.get('*', (req, res) => { res.sendFile(path.join(__dirname, '../../build', 'index.html')); }); // 启动服务 server.start().then(() => { server.applyMiddleware({ app }); mongoose .connect(MONGODB, { useNewUrlParser: true,useUnifiedTopology: true }) .then(() => { console.log('MongoDB Connected'); app.listen({ port: ports }, () => { console.log(`Server running at http://localhost:${ports}${server.graphqlPath}`); }) }); })
核心问题3:Heroku部署脚本配置缺失
Heroku默认执行根目录package.json的build和start脚本,你当前项目没有根目录的配置文件,会导致部署时无法正确构建前端、启动后端。
修改方案:
在项目最外层根目录新增package.json,内容如下:
{ "name": "cook-it-fullstack", "version": "1.0.0", "scripts": { "build": "cd frontend && npm install && npm run build", "start": "cd frontend/backend && npm install && npm start" }, "engines": { "node": "14.x" // 替换为你本地开发用的Node版本,避免版本兼容问题 } }
其他必要配置
- 数据库连接配置不要硬编码到代码中,把MongoDB连接字符串添加到Heroku后台的
Settings -> Config Vars里,变量名设为MONGODB即可。 - 如果采用前后端分开部署的方案,前端的接口地址要替换为你的Heroku后端服务的完整域名,同时后端要配置CORS允许前端域名跨域访问。
内容的提问来源于stack exchange,提问作者JayS
相关产品推荐
相关产品推荐

