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

Nodemailer实现的联系表单为何会随机发送全为undefined的内容邮件?

问题触发原因

  • 前端表单字段仅设置了id属性,未设置name属性:原生表单提交或者未适配id取值的前端提交逻辑,无法正确携带字段值到服务端。
  • 前端required校验仅在用户通过浏览器正常访问页面提交时生效,爬虫、自动化脚本可以直接绕过前端页面,调用服务端POST /接口提交空参数,直接触发undefined问题。
  • 服务端未做任何参数合法性校验,直接读取req.body下的字段拼接邮件内容,字段不存在时返回的undefined会直接带入邮件。

修复方案

1. 补充前端表单的name属性

给所有输入字段补充和服务端读取逻辑对应的name属性,修改后HTML代码如下:

<form action="#" class="row contact-form">
    <div class="col-lg-6 col-md-6 mb-3"><input type="text" placeholder="First Name"
            id="inputFirstName" name="nameFirst" class="shadow form-control form-control-lg" required></div>
    <div class="col-lg-6 col-md-6 mb-3"><input type="text" placeholder="Last Name"
            id="inputLastName" name="nameLast" class="shadow form-control form-control-lg" required></div>
    <div class="col-lg-12 mb-3"><input type="email" placeholder="Email Address" id="inputEmail"
            name="email" class="shadow form-control form-control-lg" required></div>
    <div class="col-lg-12 mb-3">
        <textarea name="message" id="message" rows="8"
            class="shadow form-control form-control-lg" required></textarea>
    </div>
    <div class="text-center d-grid mt-1">
      
      <button type="submit" class="btn btn-primary rounded-pill pt-3 pb-3">
            Send Message
            <i class="fas fa-paper-plane"></i>
    </button> 
    </div>
</form>

同时建议将邮箱输入框的type从text改为email,增加前端原生格式校验。

2. 增加服务端参数校验

在调用Nodemailer发邮件前先校验所有必填参数是否存在,示例代码如下:

//Contact Form
app.post("/", (req, res) => {
  // 新增参数校验逻辑
  const { nameFirst, nameLast, email, message } = req.body;
  if (!nameFirst?.trim() || !nameLast?.trim() || !email?.trim() || !message?.trim()) {
    return res.status(400).send('参数不完整');
  }
  // 邮箱格式校验可选补充
  const emailReg = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  if (!emailReg.test(email)) {
    return res.status(400).send('邮箱格式非法');
  }

  //Nodemailer Transporter
  const smtpTransport = nodemailer.createTransport({
    service: "gmail",
    auth: {
      type: "OAuth2",
      user: process.env.EMAIL,
      accessToken: accessToken,
      clientId: process.env.CLIENT_ID,
      clientSecret: process.env.CLIENT_SECRET,
      refreshToken: process.env.REFRESH_TOKEN,
    },
  });
  // Nodemailer options
  let mailOptions = {
    from: email,
    to: process.env.EMAIL,
    subject: `Message from ${email}`,
    text: `${nameFirst}  ${nameLast} \n  ${message}`,
  };
  //Nodemailer Transporter/Sendmail
  smtpTransport.sendMail(mailOptions, (error, info) => {
    if (error) {
      res.send("error");
    } else {
      res.send("success");
    }
  });
});

3. 可选优化项

  • 前端增加表单提交前的JS校验,双重拦截非法提交
  • 接口增加CSRF校验,阻止跨站恶意请求
  • 可添加简单的人机校验进一步拦截爬虫请求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 17:24:01