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

Node.js+Nodemailer:从表单获取发件人邮箱并解决显示异常

问题描述

我想从表单输入中获取用户的邮箱作为邮件的from字段,但现在收件人看到的发件人被替换成了SMTP认证的邮箱,导致发件人和预期不符。以下是我的前端表单代码和Node.js后端代码:

前端代码

<p class="drop">Drop A Message</p>
<label for="name">Name:</label><br>
<input type="text" name="" id="name" class="form-inputs" placeholder="Full Name" ><br>
<label for="email">Email:</label><br>
<input type="email" name="" id="email" class="form-inputs" placeholder="Email Address" ><br>
<label for="subject">Subject:</label><br>
<input type="text" name="" id="subject" class="form-inputs" placeholder="Subject Of The Message"><br>
<label for="message">Message:</label><br>
<textarea name="" id="mainMessage" cols="30" rows="10" class="message_body" ></textarea><br>
<input type="submit" value="Send Message" class="submit_btn">
</form>

Node.js后端代码

app.post('/', (req,res) =>{
    // console.log(req.body);

    const transporter = nodemailer.createTransport(smtpTransport({
        service:'Gmail',
        // host: 'smtp.gmail.com',
        secure:false,
        auth: {
            user: 'horiyorrmi72@gmail.com',
            pass: 'password'
        }
    }))

    
    const mailOptions = {
        from: req.body.email,
        to : "horla_tech@protonmail.com",
        subject: `${req.body.subject}`,
        text : req.body.message
    }

    transporter.sendMail(mailOptions, (error, info) =>{
        if(error){
            console.log(error);
            res.send('error');
            
        }else{
            console.log('Email sent' + info.response);
            res.send('success');

        }
    })
})


app.listen(PORT, ()=> {
    console.log(`server running on port: ${PORT}`);
})
解决方案

核心问题原因

Gmail的SMTP服务有安全限制:当你用Gmail账户认证发送邮件时,from字段会被强制替换为你的认证邮箱(horiyorrmi72@gmail.com),不允许直接伪造发件人地址,这就是你看到发件人不符合预期的原因。

分步修复

  1. 补全前端表单的name属性
    当前表单输入框的name为空,后端无法正确获取表单字段值,必须给每个输入框添加对应的name:
<input type="text" name="name" id="name" class="form-inputs" placeholder="Full Name" ><br>
<input type="email" name="email" id="email" class="form-inputs" placeholder="Email Address" ><br>
<input type="text" name="subject" id="subject" class="form-inputs" placeholder="Subject Of The Message"><br>
<textarea name="message" id="mainMessage" cols="30" rows="10" class="message_body" ></textarea><br>
  1. 调整后端邮件配置
  • from字段使用认证邮箱,但可以附加用户的名称和邮箱作为显示名称;
  • 添加replyTo字段指向用户输入的邮箱,这样收件人回复时会直接发送给用户;
  • 开启secure: true适配Gmail的SSL端口,避免连接错误。

调整后的后端代码:

app.post('/', (req,res) =>{
    const transporter = nodemailer.createTransport({
        service:'Gmail',
        secure: true, // 启用SSL连接
        auth: {
            user: 'horiyorrmi72@gmail.com',
            pass: 'password' // 建议使用Gmail应用专用密码,需开启两步验证
        }
    })

    const mailOptions = {
        from: `${req.body.name} <horiyorrmi72@gmail.com>`, // 显示用户名称+认证邮箱
        replyTo: req.body.email, // 设置回复邮箱为用户输入的地址
        to : "horla_tech@protonmail.com",
        subject: req.body.subject,
        text : `来自${req.body.name}的消息:\n${req.body.message}\n联系邮箱:${req.body.email}`
    }

    transporter.sendMail(mailOptions, (error, info) =>{
        if(error){
            console.log(error);
            res.send('error');
        }else{
            console.log('Email sent: ' + info.response);
            res.send('success');
        }
    })
})
  1. Gmail账户必要设置
  • 若使用普通密码,需开启Gmail的"不太安全的应用访问";
  • 更安全的方式是开启两步验证后,创建应用专用密码替代原账户密码;
  • 确保Gmail SMTP服务未被限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 00:10:37