在 heroku 上部署后端时出现 cors 错误

时间:2021-07-16 08:13:34

标签: node.js reactjs cors

我正在创建一个迷你服务器 o Node JS 我已经将它推送到了 heroku。这是一个非常简单的应用程序。只需填写您可以输入姓名和电子邮件的表单,提交表单后,数据将发布到数据库中,并通过 nodemailer 将这些数据发送到电子邮件。我是 nodeJS 的新手,所以这只是我的做法。当我在本地主机上时一切正常。但是当我将我的服务器发布到 heroku 并将我的前端发布到我的主机时,我在控制台中收到此错误: enter image description here

还有网络标签中的这个错误: enter image description here

我对 CORS 政策做了一些研究。所以在我的服务器中,我添加了 cors 依赖项并像这样使用它。

enter image description here

这是我的服务器代码:

require("dotenv").config();
const express = require("express");
const mySql = require("mysql");
const cors = require("cors");
const nodemailer = require("nodemailer");

const app = express();
app.use(cors());
app.use(express.urlencoded({ extended: false }));
app.use(express.json());

//Email
app.post("/send_email", cors(), async (req, res) => {
  let customer = req.body;
  const transport = nodemailer.createTransport({
    host: process.env.MAIL_HOST,
    port: process.env.MAIL_PORT,
    auth: {
      user: process.env.MAIL_USER,
      pass: process.env.MAIL_PASSWORD,
    },
    secure: true,
    tls: {
      rejectUnauthorized: false,
    },
  });

  try {
    await transport.sendMail({
      from: `${customer.email}`,
      to: "test@test.sk",
      subject: "Testovací email",
      html: `<h1>Objednávka</h1>
              <p>Od: ${customer.firstName} ${customer.lastName}</p>
              <p>Email: ${customer.email}</p>
      `,
    });
    console.log("Email bol úspešne odoslaný");
    return;
  } catch (error) {
    console.log("Odoslanie emailu nebolo úspešné: ", error);
  }
});

//database config
const db = mySql.createConnection({
  user: process.env.DATABASE_NAME,
  host: process.env.DATABASE_HOST,
  password: process.env.DATABASE_PASSWORD,
  database: process.env.DATABASE_NAME,
  port: process.env.DATABASE_PORT,
});

db.connect((err) => {
  if (err) {
    return console.error("error: " + err.message);
  }

  console.log("Pripojené k databáze");
});

app.post("/addCustomer", cors(), async (req, res) => {
  const firstName = req.body.firstName;
  const lastName = req.body.lastName;
  const email = req.body.email;

  try {
    await db.query(
      "INSERT INTO customers (first_name, last_name, email) VALUES (?,?,?)",
      [firstName, lastName, email],
      (err, result) => {
        if (err) {
          console.log(err);
        } else {
          res.send("Values inserted");
        }
      }
    );
  } catch (error) {
    console.log(error);
  }
});

const port = process.env.PORT || 3001;

app.listen(port, () => {
  console.log(`Server started on port ${port}`);
});

我的前端代码:

import { useState } from "react";
import { Form, Button, Row, Col } from "react-bootstrap";
import axios from "axios";

const App = () => {
  const [customer, setCustomer] = useState({
    firstName: "",
    lastName: "",
    email: "",
  });

  const handleInputs = (e) => {
    setCustomer({
      ...customer,
      [e.target.name]: e.target.value,
    });
  };

  const handleSent = () => {
    axios.post("https://simple-form-my-first-node-app.herokuapp.com/send_email", customer);
  };

  const addCustomer = (e) => {
    e.preventDefault();
    handleSent();
    axios.post("https://simple-form-my-first-node-app.herokuapp.com/addCustomer", customer).then(() => {
      console.log("úspešne!");
    });
  };

  return (
    <Form className="my-5 mx-5">
      <Form.Group as={Row}>
        <Form.Label column sm={2} className="mb-3">
          Meno
        </Form.Label>
        <Col sm={6}>
          <Form.Control
            type="text"
            placeholder="Zadaj krstné meno"
            name="firstName"
            value={customer.firstName}
            onChange={handleInputs}
          />
        </Col>
      </Form.Group>

      <Form.Group as={Row}>
        <Form.Label column sm={2} className="mb-3">
          Priezvisko
        </Form.Label>
        <Col sm={6}>
          <Form.Control
            type="text"
            placeholder="Zadaj priezvisko"
            name="lastName"
            value={customer.lastName}
            onChange={handleInputs}
          />
        </Col>
      </Form.Group>

      <Form.Group as={Row}>
        <Form.Label column sm={2} className="mb-3">
          Email
        </Form.Label>
        <Col sm={6}>
          <Form.Control
            type="email"
            placeholder="Zadaj email"
            name="email"
            value={customer.email}
            onChange={handleInputs}
          />
        </Col>
      </Form.Group>

      <Form.Group as={Row} className="mb-3">
        <Col sm={{ span: 10, offset: 2 }}>
          <Button type="submit" onClick={addCustomer}>
            Odoslať
          </Button>
        </Col>
      </Form.Group>
    </Form>
  );
};

export default App;

感谢您的高级帮助。

2 个答案:

答案 0 :(得分:0)

如果您使用

app.use(cors());

作为中间件,您不需要在端点中再次调用它

app.post("/send_email", async (req, res, next())

我相信您实际上发送了两次响应标头

答案 1 :(得分:0)

终于成功了。我犯的第一个错误是,当我将应用程序发布到 heroku 时,我没有意识到我的 .env 文件未包含在内。所以我用 heroku config:set 命令来做到这一点。我想在这里提一下,在这里输入密码时要小心,因为它不带 ^ 符号。

第二件事是我的 package.json 文件中的脚本部分 start: node index.js 中没有,所以当我将我的应用程序推送到 heroku 时,该应用程序甚至没有启动。