mysql - 为什么我的 React 应用程序(具有 Node 和 mysql 后端)可以在本地运行,但不能在 Heroku 上运行?

标签 mysql node.js reactjs heroku

初始请求的归属路由是“http://localhost:5000/contacts ”。部署到 Heroku 后,UI 已呈现,但数据未呈现,并且我收到状态 404:未找到。显示的网址是:“https://powerful-gorge-20271.herokuapp.com/contacts”。我使用 heroku 上的 Clear-DB 插件作为我的 mySql 数据库。我尝试将react应用程序的package.json文件中的代理从“http://localhost:5000 ”修改为heroku url,但这不起作用。该应用程序的存储库是:https://github.com/aosante/React-Contact-Manager

我用了这篇文章https://daveceddia.com/deploy-react-express-app-heroku/寻求指导,但仍然不起作用

这是app.js文件中的代码

const express = require('express');
const cors = require('cors');
const mysql = require('mysql');
const path = require('path');

const port = process.env.PORT || 4000;
const app = express();

//Static file declaration
app.use(express.static(path.join(__dirname, 'client/build')));

//production mode
if (process.env.NODE_ENV === 'production') {
  app.use(express.static(path.join(__dirname, 'client/build')));
  app.get('*', (req, res) => {
    res.sendfile(path.join((__dirname, 'client/build', 'index.html')));
  });
}

app.use(cors());

const SELECT_ALL_CONTACTS = `SELECT * FROM contacts ORDER BY firstName ASC`;

//Connection creation to mysql database
const connection = mysql.createConnection({
  host: 'host goes here',
  user: 'user goes here',
  port: 'goes here',
  password: 'password goes here',
  database: 'heroku_cdf7d751774d818',
  insecureAuth: true
});



 connection.connect(err => {
  if (err) console.log(err);
});

//Server start
app.listen(port, () => {
  console.log('Server started on port ' + port);
});

app.get('/api', (req, res) => {
  connection.query(SELECT_ALL_CONTACTS, (err, results) => {
    if (err) {
      res.send(err);
    } else {
      return res.json({
        data: results
      });
    }
  });
});

app.get('/api/contacts', (req, res) => {
  connection.query(SELECT_ALL_CONTACTS, (err, results) => {
    if (err) {
      res.send(err);
    } else {
      return res.json({
        data: results
      });
    }
  });
});

app.post('/api/contacts/add', (req, res) => {
  const { firstName, lastName, email, phone } = req.query;
  const INSERT_CONTACT = `INSERT INTO contacts (firstName, lastName, email, phone) VALUES ('${firstName}', '${lastName}', '${email}', '${phone}')`;
  connection.query(INSERT_CONTACT, (err, results) => {
    if (err) {
      console.log(err);
    } else {
      return res.send(results);
    }
  });
});

app.delete('/api/contacts/delete/:id', (req, res) => {
  const { id } = req.params;
  const DELETE_CONTACT = `DELETE FROM contacts WHERE id = ${id}`;
  connection.query(DELETE_CONTACT, (err, results) => {
    if (err) {
      console.log(err);
    } else {
      return res.send(results);
    }
  });
});

app.get('/api/contacts/edit/:id', (req, res) => {
  const { id } = req.params;
  const GET_CONTACT = `SELECT * FROM contacts WHERE id = ${id}`;
  connection.query(GET_CONTACT, (err, results) => {
    if (err) {
      res.send(err);
    } else {
      return res.json({
        data: results
      });
    }
  });
});

app.put('/api/contacts/update/:id', (req, res) => {
  const { id } = req.params;
  const { firstName, lastName, email, phone } = req.query;
  const UPDATE_CONTACT = `UPDATE contacts SET firstName = '${firstName}', lastName = '${lastName}', email = '${email}', phone = '${phone}' WHERE id = ${id}`;
  connection.query(UPDATE_CONTACT, (err, results) => {
    if (err) {
      console.log(err);
    } else {
      res.send(results);
    }
  });
});

//production mode
if (process.env.NODE_ENV === 'production') {
  app.use(express.static(path.join(__dirname, 'client/build')));
  app.get('*', (req, res) => {
    res.sendFile(path.join((__dirname, 'client/build', 'index.html')));
  });
}

//this goes in the end after all the requests
//build mode
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname + '/client/public/index.html'));
});

这是 package.json 文件中的内容:

{
  "name": "react-contact-manager",
  "version": "1.0.0",
  "description": "Simple contact manager with mysql backend",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "nodemon app.js",
    "client-install": "npm install --prefix client",
    "client": "npm start --prefix client",
    "dev": "concurrently \"npm run server\" \"npm run client\"",
    "heroku-postbuild": "npm install --prefix client && npm run build - -prefix client"
  },
  "keywords": [
    "react",
    "mysql"
  ],
  "author": "Andrés Osante",
  "license": "ISC",
  "dependencies": {
    "concurrently": "^4.1.0",
    "cors": "^2.8.5",
    "express": "^4.16.4",
    "mysql": "^2.16.0",
    "nodemon": "^1.18.9"
  }
}

我还添加了一个 Procfile,上面写有“web:node app.js”,但这没有帮助

最佳答案

有几件事。路线的顺序在 Express 中很重要——先到先服务。

由于在生产中,您捕获了所有路由 app.get('*', 来为您的前端提供服务,因此其他路由永远不会被命中。您需要将其移至末尾声明其他路由后的 app.js

此外,您应该仔细定义路线,以免前端和后端之间发生冲突。我不确定您是否使用 React Router,但您在应用程序的根目录上定义了一个 get 路由 ('/')。这会和你的前端发生冲突。这似乎与 /contacts 执行相同的操作,因此请继续删除根定义。

我个人不确定,也许其他人可以添加,但在 scriptspackage.json 中,考虑重新定义 heroku-postbuild.我不确定更改目录会对应用程序产生什么影响,也许什么也没有。但这里有另一种处理方法:

"heroku-postbuild": "npm install --prefix client && npm run build --prefix client"

关于mysql - 为什么我的 React 应用程序(具有 Node 和 mysql 后端)可以在本地运行,但不能在 Heroku 上运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54240357/

相关文章:

mysql - 左连接,其中左表列 = 某些内容或 null

php - mysql中的多次插入

javascript - 使用 Nodejs 在 foreach 中进行多个 http post 调用

javascript - react : Associate values of input fields with removed components

javascript - React.js 处理事件浏览器丢失

reactjs - 如何在客户端呈现的 React 应用程序中发出服务器端请求?

php - 无法在 PHP 中查看数据库中的表

php - 使用 PHP 更新存在重复字段的数据库

json - xml2js : put parser into a function

javascript - 在循环中调用时函数返回类型未正确解析