两个独立的 Heroku(Node 后端和 React 前端)之间的通信?

Posted

技术标签:

【中文标题】两个独立的 Heroku(Node 后端和 React 前端)之间的通信?【英文标题】:Communication between two separate Heroku (Node backend & React frontend)? 【发布时间】:2020-01-06 02:42:41 【问题描述】:

我正在创建的应用程序使用 MERN 堆栈(mysql、Express、React、Node)。前端和后端分别存储在 2 个独立的 Githubs 存储库中,并托管在 2 个独立的 Heroku 实例上。前端和后端都成功部署到 Heroku。

问题是如何让前端和后端相互通信?用户应该从调用后端的前端 heroku 开始,还是应该从后端开始?

我尝试将前端代理地址设置为后端的 heroku 链接,但显然此代理地址仅用于开发环境。我尝试将服务器文件添加到前端,这消除了“无效主机标头”错误,但没有解决通信问题。

这里是前端的package.json:


  "name": "healthy-front-end",
  "version": "0.1.0",
  "private": true,
  "dependencies": 
    "axios": "^0.19.0",
    "express": "^4.17.1",
    "materialize-css": "^1.0.0-rc.2",
    "moment": "^2.24.0",
    "react": "^16.8.6",
    "react-datepicker": "^2.8.0",
    "react-dom": "^16.8.6",
    "react-modal": "^3.9.1",
    "react-moment": "^0.9.2",
    "react-router-dom": "^5.0.1",
    "react-scripts": "3.0.1"
  ,
  "scripts": 
    "start": "react-scripts start",
    "dev": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "heroku-postbuild": "npm run build"
  ,
  "proxy": "http://localhost:3001",
  "eslintConfig": 
    "extends": "react-app"
  

这里是后端 server.js:

require('dotenv').config();

const express = require('express');
const app = express();
const path = require('path');
const env = process.env.NODE_ENV || 'development';
const reactConfig = require(path.join(__dirname, '/config/config.static.json'))[env];
const PORT = process.env.PORT || 3001;

// Define middleware here
app.use(express.static(path.join(__dirname, reactConfig))); // serving react files
app.use(express.urlencoded( extended: true ));
app.use(express.json());
app.use(cors());

// Serve up static assets
if (process.env.NODE_ENV === 'production') 
  app.use(express.static('client/build'));


// Routes
require('./controllers/routes')(app);

// Start the API server
app.listen(PORT, () =>
  console.log(`????  ==> API Server now listening on PORT $PORT!`)
);

这是带有前端 url 的 config.static.json 文件:


  "development": "client/public",
  "production": "https://healthy-people-front-end.herokuapp.com/"

这里是添加了 prod url 的 config.js 文件:

let config = 
    local: 
        mysql:
            url: process.env.DB_URL,
        ,
        apiKeys:
    ,
    prod: 
        mysql:
            url: process.env.JAWSDB_URL,
        ,
        url: 'https://healthy-people-front-end.herokuapp.com/',
        apiKeys:
    
;

module.exports = config[process.env.APP_ENV || 'local'];

这里是后端的package.json:


  "name": "healthy-back-end",
  "version": "1.0.0",
  "description": "API for HealthMate App",
  "main": "server.js",
  "scripts": 
    "start": "if-env NODE_ENV=production && npm run start:prod || npm run start:dev",
    "start:prod": "node server.js",
    "start:dev": "concurrently \"nodemon --ignore 'client/*'\" \"npm run client\"",
    "dev": "concurrently \"npm start\" \"npm run client\"",
    "client": "cd ../HealthMate-frontend && npm run start"
  ,
  "author": "",
  "license": "ISC",
  "dependencies": 
    "concurrently": "^4.1.2",
    "cors": "^2.8.5",
    "dotenv": "^8.1.0",
    "express": "^4.17.1",
    "hashpass": "0.0.0",
    "mysql": "^2.17.1",
    "nodemon": "^1.19.1",
    "uuid": "^3.3.2"
  

如何让两端相互通信?非常感谢任何帮助。

【问题讨论】:

如果它们在单独的 Heroku 中使用,它们很可能不会共享相同的 localhost。您应该将后端部署到 heroku,然后在一些环境变量中将后端服务的 url 传递给前端服务。 @MaciejTrojniarz 谢谢。 localhost不是只用于本地开发吗?好主意,我将寻找有关如何在 .env 文件中包含 URL 的示例。 或者我实际上会执行以下操作:将 react bundle 发布为一些缩小的 js/css 资源(到任何服务 CDN/S3/您的后端服务),然后我的后端代码为索引提供服务。 html 文件将指向这些文件,然后您可以对前端和 api 使用相同的路径,这将消除将 url 传递给后端的需要。 感谢@MaciejTrojniarz,index.html 文件位于前端,托管在不同的 Heroku url。我不认为仍然需要将前端 url 传递给后端以便我可以提供 index.html 吗? 我添加了 config.static.json 和 config.js 文件以及更新的 server.js 文件以引用这两个添加的文件 【参考方案1】:

如果您的项目包含多个包,您可以使用 f.e. lerna:https://github.com/lerna/lerna 构建一个可部署单元。然后不要为单个应用程序使用单独的 heroku 实例。

【讨论】:

再次感谢@MaciejTrojniarz。我试图将 heroku url/hostings 分开。我想一个更好的问题:从前端主机开始并链接到后端是否更好,反之亦然。看起来两者都是可能的,因为 .env 可以包含在两者中。【参考方案2】:

我不喜欢heroku,但我知道,您需要的是一个反向代理(如nginx),它将您的静态流量重定向到您的frontend,为dist 文件夹和您的backend 提供服务为您提供 API 端点。

Alternativeley,您还可以使用express.static 在您的express 应用程序中提供dist 文件夹。但是,您需要想出一种方法来使frontend 构建在您的backend 中可用。如果您将前端发布到 npm,您可以将其添加为依赖项。

【讨论】:

谢谢。我会寻找一种将前端发布到 npm 的方法。如果可以做到这一点,那么听起来用户应该从后端 heroku url 开始。

以上是关于两个独立的 Heroku(Node 后端和 React 前端)之间的通信?的主要内容,如果未能解决你的问题,请参考以下文章

用于后端和前端的Angular 2 + Node JS

在 Rails 中分离后端和前端服务器

使用来自node.js的angularjs中的json数据作为后端和sql db

我将前端和后端应用程序上传到 Heroku,但无法使用 jwt()

如何将数据从 Heroku 上托管的 Node.js 应用程序发送到托管在完全独立(Cpanel)服务器上的 PHP 文件?

将简单的 Node.js 和 Socket.io 聊天应用程序与 Rails 应用程序连接起来(在 Heroku 上)