Node.js/React 表单提交

Node.js/React Form submission

所以我在我的网站上建立了一个联系表单,但我的表单不会提交。端口 5000 和 8080 都不起作用。我正在使用 Node.js、Express、nodemailer 和 cors。我已经尝试了各种方法,例如不同的端口、确保端口已打开、更改本地主机详细信息、在文件树中移动文件等。我完全不知所措。

代码如下:

联系表:

    import React, { useState} from 'react'
// import "./contact.scss"


const ContactForm = () => {
    
    const [status, setStatus] = useState("Submit");
    const handleSubmit = async (e) => {
      e.preventDefault();
      setStatus("Sending...");
      const { name, email, message } = e.target.elements;
      let details = {
        name: name.value,
        email: email.value,
        message: message.value,
      };
      let response = await fetch("http://localhost:8080/contact", {
        method: "POST",
        headers: {
          "Content-Type": "application/json;charset=utf-8",
        },
        body: JSON.stringify(details),
      });
      setStatus("Submit");
      let result = await response.json();
      alert(result.status);
    };
    return (
        <div className="right">
          <div className="rightcontainer">
            <h3>Your Information Below</h3>
            <form onSubmit={handleSubmit}>
            <div>
              <label htmlFor="name">Name:</label>
              <input
              style={
                {width: '100%', 
                height: '40px', 
                margin: '10px'} 
                } className='name' type="text" id="name" placeholder="Name" required />
            </div>
            <div>
              <label htmlFor="email">Email:</label>
              <input
              style={
                {width: '100%', 
                height: '40px', 
                margin: '10px'} 
                } className='email' type="email" id="email" placeholder="Email" required />
            </div>
            <div>
              <label htmlFor="message">Message:</label>
              <textarea 
              style={
                {width: '100%', 
                height: '100px', 
                margin: '10px',
                } 
                } id="message" placeholder="message" required />
            </div>
            <button
            style={
              {width: '100%', 
              height: '40px', 
              margin: '10px'} 
              } type="submit" className='button'>{status}</button>
            </form>
          </div>
        </div>
      );
}

export default ContactForm

Server.js 文件:

const express = require("express");
const router = express.Router();
const cors = require("cors");
const nodemailer = require("nodemailer");

const app = express();
app.use(cors());
app.use(express.json());
app.use("/", router);
app.listen(8080, () => console.log("Server Running"));

const contactEmail = nodemailer.createTransport({
    service: 'gmail',
    auth: {
      user: "************@gmail.com",
      pass: "************",
    },
  });
  
  contactEmail.verify((error) => {
    if (error) {
      console.log(error);
    } else {
      console.log("Ready to Send");
    }
  });

  router.post("/contact", (req, res) => {
    const name = req.body.name;
    const email = req.body.email;
    const message = req.body.message; 
    const mail = {
      from: name,
      to: "************@gmail.com",
      subject: "Contact Form Submission",
      html: `<p>Name: ${name}</p>
             <p>Email: ${email}</p>
             <p>Message: ${message}</p>`,
    };
    contactEmail.sendMail(mail, (error) => {
      if (error) {
        res.json({ status: "ERROR" });
      } else {
        res.json({ status: "Message Sent" });
      }
    });
  });

联系页面:

import "./contact.scss"
import ContactForm from "../../ContactForm";
import {Mail, GitHub, LinkedIn} from '@material-ui/icons/';
import React from 'react';


export default function Contact() {
  return (
    <div className='contact' id="contact">
      <div className="left">
        <div className="leftContainer">
            <div className="imgContainer">
                <Mail className="people"/>
            </div>
            <h2>Contact Me</h2>
            <p>
                If you would like to hire me on a contractual basis or hire me on a per project basis please use the form, alternatively contact me through:
            </p>
            <div className="icons">
              <a href="https://www.linkedin.com/in/jake-gliddon-5199481b7/"><LinkedIn className="icon"/></a>
              <a href="https://github.com/jake-gliddon"><GitHub className="icon" /></a>
            </div>
          </div>
      </div>
      <div className="right">
        <div className="rightContainer mobile">
          <ContactForm />
        </div>
      </div>
      </div>

  )
}

任何帮助将不胜感激!

好的,所以我认为您的问题出在后端的 /contact 路由中。在路由器回调函数中,您试图访问字符串的属性 nameemailmessage,而不是对象。在您的 ContactForm 组件中,您有这一行:body: JSON.stringify(details),。这意味着在后端您需要将此 JSON 解析为可读的 javascript 对象,如下所示:JSON.parse(req.body)。这是完整的代码:

  router.post("/contact", (req, res) => {
    // short for Parsed Body
    const pB = JSON.parse(req.body);
    const name = pB.name;
    const email = pB.email;
    const message = pB.message; 
    const mail = {
      from: name,
      to: "************@gmail.com",
      subject: "Contact Form Submission",
      html: `<p>Name: ${name}</p>
             <p>Email: ${email}</p>
             <p>Message: ${message}</p>`,
    };
    contactEmail.sendMail(mail, (error) => {
      if (error) {
        res.json({ status: "ERROR" });
      } else {
        res.json({ status: "Message Sent" });
      }
    });
  });

此外,如果您想要一种更简单的方法来从客户端发出 POST 请求,我建议您使用库 axios.

至于您的文件结构,它应该如下所示:

那么你应该打开两个终端 windows。在一个中你启动你的反应应用程序:

/client $ npm start

然后在另一个中启动服务器

/server $ node server.js

它们都应该由 npm 单独启动,所以创建一个 server 目录,然后将你的 server.js 文件移到那里,并安装你的依赖项。与 client 目录相同。

此外,我建议在 public 存储库中为您的电子邮件详细信息使用环境变量。尝试在您的服务器中使用 dotenv

当我尝试 运行 server.js 文件时,出现无效登录错误。这可能只是在我这边,但它可能是您需要解决的下一个问题。我还必须将端口从 5000 切换到 8080,如果您正在使用 mac,则此端口上可能有某种类型的服务 运行。