我正在尝试在我的React网站中使用SendGrid模块实现联系表单以发送电子邮件。我在一个名为server.js的文件中有服务器端代码,在card. tsx中有客户端代码。当我运行npm start时,我遇到了一个与SendGrid包中的fs和path模块相关的错误。另外,我在Contact.tsx文件中的类型检查有问题。如何解决这些错误并使联系表格正常工作?
下面是我在server.js中的服务器端代码:
// server.js
const express = require("express");
const sgMail = require("@sendgrid/mail");
const { resolve } = require("path-browserify");
// Set up SendGrid API key
sgMail.setApiKey("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");
// Create Express app
const app = express();
// Middleware to parse JSON requests
app.use(express.json());
app.get("/", (req, res) => {
res.send("Hello, server!");
});
// Route to handle sending emails
app.post("/send-email", (req, res) => {
const { Name, Email, Message, submitbutton } = req.body;
const msg = {
to: "paristiffany12@gmail.com",
from: "gdscusyd@gmail.com",
subject: "Example Subject",
text: `Name: ${Name}\nEmail: ${Email}\nMessage: ${Message}\nSubmit Button: ${submitbutton}`,
html: `<p>Name: ${Name}</p><p>Email: ${Email}</p><p>Message: ${Message}</p><p>Submit Button: ${submitbutton}</p>`,
};
sgMail
.send(msg)
.then(() => {
res.status(200).json({ message: "Email sent successfully" });
})
.catch((error) => {
console.error(error.toString());
res.status(500).json({ error: "Failed to send email" });
});
});
// Set up fallback for path module
resolve.fallback = { path: require.resolve("path-browserify") };
// Start the server
app.listen(4000, () => {
console.log("Server started on port 3000");
});
下面是card.tsx中的客户端代码(联系表单的代码):
import React, { useState, useEffect, useRef } from "react";
import cardcss from "./Card.module.css";
import axios from "axios";
interface CardProps {
imageUrl: string;
title: string;
body: string;
}
function Card(props: CardProps) {
const [message, setMessage] = useState("");
const nameInputRef = useRef<HTMLInputElement>(null);
const emailInputRef = useRef<HTMLInputElement>(null);
const messageInputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
if (messageInputRef.current) {
messageInputRef.current.focus();
messageInputRef.current.setSelectionRange(0, 0);
// Delay setting the cursor position
setTimeout(() => {
messageInputRef.current?.setSelectionRange(0, 0);
}, 0);
}
}, []);
const handleFocus = (event: React.FocusEvent<HTMLInputElement>) => {
event.target.setSelectionRange(0, 0);
};
const submitHandler = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (
nameInputRef.current &&
emailInputRef.current &&
messageInputRef.current
) {
const nameInput = nameInputRef.current.value;
const emailInput = emailInputRef.current.value;
const messageInput = messageInputRef.current.value;
const contactData = {
Name: nameInput,
Email: emailInput,
Message: messageInput,
};
axios
.post("/send-email", contactData)
.then((response) => {
console.log(response.data);
// Handle success response
})
.catch((error) => {
console.error(error);
// Handle error response
});
}
};
return (
<div className={cardcss.cardcontainer}>
<div className={cardcss.imagecontainer}>
<img src={props.imageUrl} alt="" />
</div>
<div className={cardcss.cardtitle}>
<h3>{props.title}</h3>
</div>
<div className={cardcss.cardbody}>
<p>{props.body}</p>
<form onSubmit={submitHandler}>
<div>
<label className={cardcss.namelabel} htmlFor="name">
Name:
</label>
<input
className={cardcss.nameinput}
type="text"
id="name"
name="name"
ref={nameInputRef}
/>
</div>
<div className={cardcss.emailcontainer}>
<label className={cardcss.emaillabel} htmlFor="email">
Email:
</label>
<input
className={cardcss.emailinput}
type="text"
id="email"
name="email"
ref={emailInputRef}
/>
</div>
<div className={cardcss.messagecontainer}>
<label className={cardcss.messagelabel} htmlFor="message">
Message:
</label>
<input
ref={messageInputRef}
className={cardcss.messageinput}
type="text"
id="message"
name="message"
value={message}
onChange={(e) => setMessage(e.target.value)}
onFocus={handleFocus}
/>
<button className={cardcss.sendbutton} type="submit">
Send
</button>
</div>
</form>
</div>
</div>
);
}
export default Card;
下面是我的联系人页面代码:
import React, { useRef } from "react";
import contactcss from "./Contact.module.css";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import Card from "../../components/ui/Card";
import {
faInstagram,
faFacebook,
faLinkedin,
faDiscord,
} from "@fortawesome/free-brands-svg-icons";
import emaillogo from "../../resources/email-logo.png";
import { setApiKey, send } from "@sendgrid/mail";
const Contact: React.FC = () => {
const inputRef = useRef<HTMLInputElement>(null);
const handleClick = () => {
if (inputRef.current) {
inputRef.current.focus();
inputRef.current.setSelectionRange(0, 0);
}
};
setApiKey(
"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"
);
function submitFormHandler(contactData: {
Name: string;
Email: string;
Message: string;
}) {
const { Name, Email, Message } = contactData;
const msg = {
to: "paristiffany12@gmail.com",
from: Email,
subject: "GDSC Contact Form - New Message",
text: `Message from: ${Name}\nMessage: ${Message}`,
html: `<p>Message from: ${Name}</p><p>Message: ${Message}</p>`,
};
send(msg)
.then(() => {
console.log("Email sent successfully");
})
.catch((error) => {
console.error(error.toString());
});
}
return (
<div>
<div>
<div className={contactcss.background}>
<img
className={contactcss.emaillogo}
src={emaillogo}
alt="Contact Us"
/>
<div className={contactcss.contact}>Contact Us</div>
</div>
</div>
<Card
title="We're keen to hear from you!"
imageUrl="https://images.app.goo.gl/D6m6hHMnP1gjsKKV7"
body=""
onSubmitForm={submitFormHandler}
/>
<div className={contactcss.whitebackground}>
<div className={contactcss.socials}>
<h1>Follow Our Socials</h1>
<p className={contactcss.socialmedia}>
Stay connected with GDSC USYD by following us on our social media
channels:
</p>
<div>
<a href="https://www.instagram.com/gdscusyd/">
<FontAwesomeIcon
className={contactcss.instagram}
icon={faInstagram}
/>
</a>
<a href="https://www.facebook.com/gdsc.usyd">
<FontAwesomeIcon
className={contactcss.facebook}
icon={faFacebook}
/>
</a>
<a href="https://discord.com/channels/872033047652990986/872033047652990989">
<FontAwesomeIcon
className={contactcss.discord}
icon={faDiscord}
/>
</a>
<a href="https://www.linkedin.com/company/gdsc-usyd/">
<FontAwesomeIcon
className={contactcss.linkedin}
icon={faLinkedin}
/>
</a>
</div>
</div>
</div>
</div>
);
};
export default Contact;
错误消息:
编译失败。未找到模块:错误:无法解析'fs' in '/Users/parisvinuya/RARYA - GDSC WEBSITE/gdsc-website/main/node_modules/@sendgrid/helpers/classes'
我想知道我如何才能让这个联系表格工作?我已经把服务器端代码和客户端代码分开了,但是网站仍然没有运行……谢谢你的帮助!
1条答案
按热度按时间kyxcudwk1#
首先,你不应该在客户端实现SendGrid API(React)。您的联系人表单应该包含将表单数据发送到后端的逻辑,并让后端实现发送电子邮件的逻辑。
这样,您就可以在应用程序的客户端和服务器端使用相同的包。正如我在前一段中所说的,你不应该在客户端实现电子邮件逻辑。在客户端保存和发送API密钥既不安全也不负责,因为它很容易被盗。
在编译客户端代码时遇到
fs
错误的原因是客户端(浏览器运行JavaScript)不包含fs
模块。fs
模块代表文件系统,仅在操作系统上运行的NodeJS中实现。要修复此问题,请从客户端删除与SendGrid相关的所有逻辑,并让服务器端API接收表单输入并将所需消息发送给用户。
换句话说,接触组件:
有了上面的更改,您应该重构服务器端代码,以接收数据并使用API向用户发送电子邮件。我还没看过后端代码所以要做出相应的改变
希望这个答案有用。