You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React+Express集成SendGrid发送POST请求遇404错误求助

React + Express + SendGrid 邮件发送POST请求404错误

错误信息

xhr.js:210 POST http://localhost:3000/send-email 404 (Not Found)

前端代码(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);

      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,
      };
      console.log(contactData);

      axios
        .post("http://localhost:3000/send-email", contactData)
        .then((response) => {
          console.log("Received email request");
        })
        .catch((error) => {
          console.error(error);
        });
    }
  };

  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;

后端代码(server.js)

const express = require("express");
const sgMail = require("@sendgrid/mail");
const { resolve } = require("path-browserify");

sgMail.setApiKey(
  "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"
);

const app = express();

app.use(express.json());

app.get("/", (req, res) => {
  res.send("Hello, server!");
});

app.post("/send-email", (req, res) => {
  const { Name, Email, Message, submitbutton } = req.body;

  const msg = {
    to: "paristiffany12@gmail.com",
    from: "paristiffany12@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" });
    });
});

resolve.fallback = { path: require.resolve("path-browserify") };

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

错误原因及解决方法

1. 端口冲突(最可能)

React开发服务器默认监听3000端口,你的Express服务器也配置了监听3000,导致React服务器抢占端口,Express无法正常启动,自然找不到/send-email路由。

解决:

  • 修改Express监听端口为其他值(比如5000):
    // server.js末尾
    app.listen(5000, () => {
      console.log("Server started on port 5000");
    });
    
  • 前端请求地址改为对应端口:
    axios.post("http://localhost:5000/send-email", contactData)
    

2. 无效的Express配置代码

server.js中resolve.fallback = { path: require.resolve("path-browserify") };是Webpack的配置项,不是Express的代码,这行代码会导致服务器启动报错,直接使Express服务无法正常运行。

解决:
删除这行代码,Express不需要该配置。

3. 前端请求路径优化(可选)

为避免跨域和端口硬编码问题,可使用React代理:

  • 在React项目的package.json中添加:
    "proxy": "http://localhost:5000"
    
  • 前端请求改为相对路径:
    axios.post("/send-email", contactData)
    

4. 验证服务器状态

启动Express后,访问http://localhost:5000/(对应修改后的端口),如果返回"Hello, server!",说明服务器正常运行;如果无法访问,检查服务器启动日志是否有报错。


内容的提问来源于stack exchange,提问作者user22081405

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 22:44:57