部署前端 React.js 后端 Express 应用程序时,API 出现内部服务器错误 500

发布于 2025-01-17 14:24:07 字数 5419 浏览 0 评论 0原文

对于我的高级顶点,我和我的团队开发了一个基于网络的应用程序来模拟比特币 - 使用react.js作为前端,使用node.js/express作为后端。直到最近,我们在 src 目录中拥有所有模拟创建代码(javascript 文件),这意味着它是在客户端构建的。由于从交易中所需的所有散列创建模拟的等待时间很长,我们认为我们的模拟创建代码更适合后端而不是前端。减轻客户端的负担并将其放在服务器上极大地提高了创建模拟的速度,因此“非常成功!”。

当我们进行此更改时,我们最终遇到了 require 和 import 语句的一些问题。 Reactjs 仅支持 import 语句,Express 使用 require 语句。我们必须使用我们在 API 中开发的一些 js 函数,因此我们使用 require 语句导入它们,我们认为我们认为它已经解决了,因为在我们的开发环境中,一切都运行得像黄油一样顺利,但是一旦部署,我们的登录页面无法进行 API 调用。错误是:无法加载资源:服务器响应状态为 500(内部服务器错误)。

这很有趣,因为 API 中的这条路线在从 require 到 import 进行这一重大转变之前就起作用了,并且这些更改位于其他文件/路线中。登录 API 保持完全不变。

不管怎样,我都会删除一些代码,以防它对故障排除有所帮助。 server.js

const express = require("express");
const app = express();
const router = express.Router();
const path = require("path");
var cors = require("cors");

require("dotenv").config();

app.use(express.json({ limit: "50mb" }));
app.use(express.urlencoded({ limit: "50mb" }));

app.use(function (req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header(
    "Access-Control-Allow-Headers",
    "Origin, X-Requested-With, Content-Type, Accept"
  );
  next();
});

// List of routes
router.use("/api/users", require("./api/users"));
router.use("/api/data", require("./api/data"));
router.use("/api/share", require("./api/share"));
router.use("/api/addresses", require("./api/addresses"));

const root = path.join(__dirname, "client/build");
app.use(express.static(root));

app.use(router);
app.use(cors({ origin: true, credentials: true }));

app.listen(
  process.env.PORT,
  () => `Server running on port ${process.env.PORT}`
);

api/users.js 登录路由

const express = require("express");
const app = express();
const db = require("../dbConn");
const bcrypt = require("bcrypt-nodejs");
const cors = require("cors");
const router = express.Router();
const jwt = require("jwt-simple");
const config = require("../configuration/config.json");

// to parse JSON
app.use(express.json());

router.post("/login", (req, res) => {
  //check if email and password are sent
  if (!req.body.email || !req.body.password) {
    return res.status(401).json({ error: "Missing username and/or password" });
  }
  // go into mysql and get info
  let qry = `select * from user where email = "${req.body.email}"`;
  db.query(qry, (err, rows) => {
    if (err) {
      return res.status(500).json({ error: err });
    }
    // assert: no error - process the result set
    if (rows.length == 0) {
      // no users found
      res.status(400).json({ msg: "No users found" });
    } else {
      // process the user records
      let users = [];
      rows.forEach((row) => {
        let user = {
          uid: row.uid,
          email: row.email,
          role: row.role,
          dateCreated: row.created_date,
          password: row.password,
        };
        users.push(user);
      });
      if (users[0]) {
        // Does given password hash match the database password hash?
        bcrypt.compare(req.body.password, users[0].password, (err, result) => {
          // Send back a token that contains the user's username
          const token = jwt.encode({ email: req.body.email }, config.secret);
          if (result == true) {
            res.status(200).json({
              msg: "user authenticated",
              fname: users[0].fname,
              lname: users[0].lname,
              role: users[0].role,
              token: token,
            });
          } else {
            res.sendStatus(401);
          }
        });
      }
    }
  });
});

router.post("/auth", cors(), (req, res) => {
  try {
    let user = jwt.decode(req.body.token, config.secret);
    res.status(200).send(user);
  } catch (err) {
    res.sendStatus(401);
  }
});

SignIn.js client/src/components。这是包含在react.useEffect()箭头函数中的,但我再次认为问题不在这里,因为该页面与工作版本保持不变。

const handleSubmit = (e) => {
    e.preventDefault();

    const credentials = { email, password };

    // API call to login to account
    // if successful, redirect to landing page
    // if not, display error message
    fetch(`http://${process.env.REACT_APP_API_URL}/api/users/login`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(credentials),
    })
      .then(async (res) => {
        if (res.status == 200) {
          return res.json();
        } else {
          throw new Error("Failed to Login!");
        }
      })
      .then(async (res) => {
        // Store token in cookie
        setCookie("token", res.token, { path: "/${path}", maxAge: 3600 * 24 });

        // Toggle state of sign in
        toggleSignIn();

        // Feedback
        setFeedback(true);
        setFeedbackObj({ message: "Signed in!", severity: "success" });

        //redirect
        history.push(`${process.env.PUBLIC_URL}/simulation`);
      })
      .catch(async (err) => {
        // Feedback
        setFeedback(true);
        setFeedbackObj({ message: "Sign In Error", severity: "error" });

        console.error(err);
      });
  };

如果还有其他感兴趣的文件,请告诉我。

我试图弄乱 package.json 中的代理,但我不认为这就是答案,因为它之前就可以工作。除了如何使用 Express 后端和 React.js 前端构建简单的应用程序之外,我很难找到其他有类似问题或资源的人。这不是我们的问题,因为我们的应用程序在这个重大转变之前运行得很好。我认为这个问题源于我们 API 中的 require 语句以及 API 中 JS 函数的运行。我无法确认这一点,因为在生产(部署)中,错误信息非常少,而在开发中,它运行得很好。

几周来我一直在尝试解决这个问题,但进展甚微。如果有人对部署故障排除有建议或提示,我将不胜感激。

谢谢!

For my senior capstone, my group and I have developed a web-based application to simulate Bitcoin - using react.js for the front-end and node.js/express for the back-end. Up until recently, we've had all of simulation-creating-code (javascript files) inside the src directory, meaning it was being built client-side. Due to high waiting times to create a simulation from all the hashing necessary in transactions, we decided that our simulation-creating-code would be better suited for the back-end rather than the front end. Taking the load off the client and putting it on the server drastically improved the speed of creating a simulation, so 'Great success!'.

When we made this change, we ended up having some issues with require and import statements. Reactjs only supports import statements and Express uses require statements. We had to use some js functions that we developed in our API's so we imported them with require statements, and we thought we thought it was resolved because on our development environment, everything runs as smooth as butter, but once it's deployed, our login page is unable to make an API call. The error is: Failed to load resource: the server responded with a status of 500 (Internal Server Error).

It's interesting because this route in the API worked prior to making this big switch from require to import, and those changes were in other files/routes. The login API remains completely unchanged.

Either way, I'll drop some code in case it's helpful in troubleshooting.
server.js

const express = require("express");
const app = express();
const router = express.Router();
const path = require("path");
var cors = require("cors");

require("dotenv").config();

app.use(express.json({ limit: "50mb" }));
app.use(express.urlencoded({ limit: "50mb" }));

app.use(function (req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header(
    "Access-Control-Allow-Headers",
    "Origin, X-Requested-With, Content-Type, Accept"
  );
  next();
});

// List of routes
router.use("/api/users", require("./api/users"));
router.use("/api/data", require("./api/data"));
router.use("/api/share", require("./api/share"));
router.use("/api/addresses", require("./api/addresses"));

const root = path.join(__dirname, "client/build");
app.use(express.static(root));

app.use(router);
app.use(cors({ origin: true, credentials: true }));

app.listen(
  process.env.PORT,
  () => `Server running on port ${process.env.PORT}`
);

api/users.js login route

const express = require("express");
const app = express();
const db = require("../dbConn");
const bcrypt = require("bcrypt-nodejs");
const cors = require("cors");
const router = express.Router();
const jwt = require("jwt-simple");
const config = require("../configuration/config.json");

// to parse JSON
app.use(express.json());

router.post("/login", (req, res) => {
  //check if email and password are sent
  if (!req.body.email || !req.body.password) {
    return res.status(401).json({ error: "Missing username and/or password" });
  }
  // go into mysql and get info
  let qry = `select * from user where email = "${req.body.email}"`;
  db.query(qry, (err, rows) => {
    if (err) {
      return res.status(500).json({ error: err });
    }
    // assert: no error - process the result set
    if (rows.length == 0) {
      // no users found
      res.status(400).json({ msg: "No users found" });
    } else {
      // process the user records
      let users = [];
      rows.forEach((row) => {
        let user = {
          uid: row.uid,
          email: row.email,
          role: row.role,
          dateCreated: row.created_date,
          password: row.password,
        };
        users.push(user);
      });
      if (users[0]) {
        // Does given password hash match the database password hash?
        bcrypt.compare(req.body.password, users[0].password, (err, result) => {
          // Send back a token that contains the user's username
          const token = jwt.encode({ email: req.body.email }, config.secret);
          if (result == true) {
            res.status(200).json({
              msg: "user authenticated",
              fname: users[0].fname,
              lname: users[0].lname,
              role: users[0].role,
              token: token,
            });
          } else {
            res.sendStatus(401);
          }
        });
      }
    }
  });
});

router.post("/auth", cors(), (req, res) => {
  try {
    let user = jwt.decode(req.body.token, config.secret);
    res.status(200).send(user);
  } catch (err) {
    res.sendStatus(401);
  }
});

SignIn.js client/src/components. This is wrapped in a react.useEffect() arrow function, but again I don't believe the issue is here because this page remains unchanged from a working version.

const handleSubmit = (e) => {
    e.preventDefault();

    const credentials = { email, password };

    // API call to login to account
    // if successful, redirect to landing page
    // if not, display error message
    fetch(`http://${process.env.REACT_APP_API_URL}/api/users/login`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(credentials),
    })
      .then(async (res) => {
        if (res.status == 200) {
          return res.json();
        } else {
          throw new Error("Failed to Login!");
        }
      })
      .then(async (res) => {
        // Store token in cookie
        setCookie("token", res.token, { path: "/${path}", maxAge: 3600 * 24 });

        // Toggle state of sign in
        toggleSignIn();

        // Feedback
        setFeedback(true);
        setFeedbackObj({ message: "Signed in!", severity: "success" });

        //redirect
        history.push(`${process.env.PUBLIC_URL}/simulation`);
      })
      .catch(async (err) => {
        // Feedback
        setFeedback(true);
        setFeedbackObj({ message: "Sign In Error", severity: "error" });

        console.error(err);
      });
  };

If there are any other files that are of interest please let me know.

I've tried to mess with the proxy in package.json, but I don't think thats the answer because it was working previously. I've had a really difficult time finding others with similar issues or resources other than how to build a simple app with Express backend and React.js front end. This is not our issue because our application was working perfectly before this big switch. I believe the issue is stemming from require statements in our API and the running of JS functions in the API. I have no way to confirm this because in production (deployment), the errors are super uninformative, and in development, it runs perfectly fine.

I have been trying to solve this issue for a couple of weeks now, and I've made very little progress. If anyone has suggestions or tips on troubleshooting deployment, I would greatly appreciate it.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文