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

ReactJS中如何将表单数据发送至指定邮箱?

React表单提交数据到邮箱的解决方案

为什么原生action="mailto"无效?

直接给React表单设置action="mailto:example@gmail.com"通常有这些问题:

  • React单页应用默认会阻止表单的默认刷新行为,导致mailto链接无法触发
  • 即使触发,浏览器可能因为安全策略拦截请求,或者用户未关联邮件客户端
  • 原生mailto无法自动将表单字段格式化为可读的邮件内容,只能提交键值对的原始数据,可读性差

方案1:改进原生mailto实现(快速简单)

通过React受控组件收集表单数据,手动构造带格式化内容的mailto链接,触发邮件客户端。

代码示例

import { useState } from 'react';

function EmailForm() {
  const [formData, setFormData] = useState({
    name: '',
    email: '',
    message: ''
  });

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData(prev => ({ ...prev, [name]: value }));
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    // 编码主题和内容,避免特殊字符破坏链接
    const subject = encodeURIComponent('新的表单提交');
    const body = encodeURIComponent(
      `姓名: ${formData.name}\n提交者邮箱: ${formData.email}\n留言内容: ${formData.message}`
    );
    // 构造完整mailto链接
    const mailtoUrl = `mailto:example@gmail.com?subject=${subject}&body=${body}`;
    // 触发邮件客户端
    window.location.href = mailtoUrl;
  };

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>姓名:</label>
        <input
          type="text"
          name="name"
          value={formData.name}
          onChange={handleChange}
          required
        />
      </div>
      <div>
        <label>邮箱:</label>
        <input
          type="email"
          name="email"
          value={formData.email}
          onChange={handleChange}
          required
        />
      </div>
      <div>
        <label>留言:</label>
        <textarea
          name="message"
          value={formData.message}
          onChange={handleChange}
          required
        />
      </div>
      <button type="submit">提交表单</button>
    </form>
  );
}

export default EmailForm;

注意事项

  • 必须用encodeURIComponent处理主题和内容,防止空格、特殊字符导致链接失效
  • 依赖用户浏览器已关联邮件客户端(如Outlook、Thunderbird或网页邮箱)
  • 邮件内容长度有限制,过长数据可能被截断
  • 无法确认用户是否最终发送了邮件

方案2:后端接口处理(生产环境推荐)

原生mailto的局限性太多,生产环境更可靠的方式是通过后端接收表单数据,再发送邮件。以下是Node.js + Nodemailer的实现示例:

后端代码(server.js)

const express = require('express');
const nodemailer = require('nodemailer');
const cors = require('cors');
const app = express();

app.use(cors());
app.use(express.json());

// 配置邮件传输(以Gmail为例)
const transporter = nodemailer.createTransport({
  service: 'Gmail',
  auth: {
    user: 'your-email@gmail.com',
    pass: 'your-app-password' // Gmail需开启两步验证并生成应用密码
  }
});

// 接收表单数据并发送邮件的接口
app.post('/send-form-email', (req, res) => {
  const { name, email, message } = req.body;

  const mailOptions = {
    from: email,
    to: 'example@gmail.com',
    subject: `表单提交: ${name}`,
    text: `姓名: ${name}\n提交者邮箱: ${email}\n留言: ${message}`
  };

  transporter.sendMail(mailOptions, (err, info) => {
    if (err) {
      console.error(err);
      res.status(500).send('邮件发送失败');
    } else {
      console.log(`邮件已发送: ${info.response}`);
      res.status(200).send('邮件发送成功');
    }
  });
});

app.listen(3001, () => {
  console.log('后端服务运行在 http://localhost:3001');
});

React前端调用接口

import { useState } from 'react';

function EmailForm() {
  const [formData, setFormData] = useState({
    name: '',
    email: '',
    message: ''
  });
  const [submitStatus, setSubmitStatus] = useState('');

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData(prev => ({ ...prev, [name]: value }));
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    setSubmitStatus('发送中...');
    try {
      const response = await fetch('http://localhost:3001/send-form-email', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(formData)
      });
      if (response.ok) {
        setSubmitStatus('发送成功!');
        // 重置表单
        setFormData({ name: '', email: '', message: '' });
      } else {
        setSubmitStatus('发送失败,请重试');
      }
    } catch (err) {
      setSubmitStatus('网络错误,请检查连接');
      console.error(err);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>姓名:</label>
        <input
          type="text"
          name="name"
          value={formData.name}
          onChange={handleChange}
          required
        />
      </div>
      <div>
        <label>邮箱:</label>
        <input
          type="email"
          name="email"
          value={formData.email}
          onChange={handleChange}
          required
        />
      </div>
      <div>
        <label>留言:</label>
        <textarea
          name="message"
          value={formData.message}
          onChange={handleChange}
          required
        />
      </div>
      <button type="submit" disabled={submitStatus === '发送中...'}>
        {submitStatus || '提交表单'}
      </button>
      {submitStatus && <p className="status">{submitStatus}</p>}
    </form>
  );
}

export default EmailForm;

优势

  • 不依赖用户邮件客户端,只要联网就能提交
  • 支持大量数据,无长度限制
  • 能在前端给出明确的提交反馈
  • 可添加数据验证、验证码等防垃圾邮件机制

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 17:15:08