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

使用Node.js TLS Socket连接Gmail SMTP时遭遇协议违规错误

Gmail SMTP 451 协议违规问题解决

问题背景

使用Node.js的TLS Socket连接Gmail SMTP服务器,自定义SMTP命令生成类发送邮件时,MAIL FROM和RCPT TO命令能收到服务器的OK响应,但发送DATA命令后收到:

451 4.5.0 SMTP protocol violation, see RFC 2821 k12-20020adff5cc000000b0021e4c3b2966si4569901wrp.1037 - gsmtp

后续尝试中,服务器返回"Go Ahead"后发送FROM:开头的邮件头,仍收到相同的451错误。

涉及代码

TLS连接处理代码

secure.on('secureConnect', () => {
    //secure.setEncoding('base64');

    let caretka = `\r\n`;
    console.log(secure.authorized);
    console.log('IN SECURE');

    //secure.write('EHLO hailmail\r\n');
    com.forEach(command => {
        secure.write(command);
    });

    secure.write('quit\r\n');
    secure.on('data', chunk => {
        const response = chunk.toString();
        console.log(`Response in secure: ${response}`);

    })
    secure.on('keylog', (line) => {
        console.log(`Line in secure: ${line}`);
    })
    secure.on('close', () => {
        console.log('closed');
    })
});

SMTP命令生成类

class creatingCommandsForSMTP {
    constructor(msg) {
        this.helo = `EHLO hailmail\r\n`;
        this.mailFrom = `MAIL FROM: <${msg.from}>\r\n`;
        this.recipient = `RCPT TO: <${msg.recipient}>\r\n`;
        this.commandData = `DATA`;
        //this.dataFrom = `FROM: <${msg.from}>\r\n`;
        //this.dataTo = `TO: <${msg.recipient}>\r\n`;
        //this.dataSubject = `SUBJECT: ${msg.subject}\r\n`;
        //this.dataText = `${msg.text}\r\n`;
        //this.dot = `.\r\n`;
        //this.commandQuit = 'QUIT\r\n';
    }
    getValue(command) {
        return this[command]
    }
}

问题根源及修复方案

1. DATA命令格式错误

RFC 2821要求所有SMTP命令必须以\r\n结尾,你的commandData字段只写了DATA,缺少结尾的换行符,导致服务器无法识别为完整命令。修改命令生成类:

this.commandData = `DATA\r\n`;

2. 违反SMTP请求-响应交互模式

SMTP是逐命令交互的协议,必须等待服务器返回前一个命令的响应后,才能发送下一个命令。你的代码直接通过forEach一次性发送所有命令,会导致命令在TCP缓冲区堆积,服务器无法按顺序处理,触发协议违规。

重构为响应驱动的发送逻辑:

secure.on('secureConnect', () => {
    console.log(secure.authorized);
    console.log('IN SECURE');

    // 按顺序排列的命令队列
    const commands = [
        `EHLO hailmail\r\n`,
        `MAIL FROM: <your-email@gmail.com>\r\n`,
        `RCPT TO: <recipient@example.com>\r\n`,
        `DATA\r\n`,
        `FROM: <your-email@gmail.com>\r\n`,
        `TO: <recipient@example.com>\r\n`,
        `SUBJECT: Test Email\r\n`,
        `\r\n`, // 邮件头与正文的分隔空行
        `This is the email content.\r\n`,
        `.\r\n`, // 邮件内容结束标记
        `QUIT\r\n`
    ];

    let commandIndex = 0;

    // 发送第一个命令
    secure.write(commands[commandIndex]);

    secure.on('data', chunk => {
        const response = chunk.toString();
        console.log(`Response: ${response}`);

        // 2xx/3xx响应表示可以继续发送下一个命令
        if ((response.startsWith('2') || response.startsWith('3')) && commandIndex < commands.length - 1) {
            commandIndex++;
            secure.write(commands[commandIndex]);
        }
    });

    secure.on('close', () => {
        console.log('closed');
    });
});

3. 邮件内容格式规范

服务器返回354 Go Ahead后,发送的邮件内容必须符合RFC 2822格式:

  • 邮件头和正文之间必须有一个空行(\r\n)
  • 邮件内容必须以单独一行的.结束(即.\r\n)
  • 如果邮件内容中有行以.开头,需要转写成..,避免被误判为结束标记

额外注意事项

Gmail SMTP的强制要求:

  • 必须使用TLS加密(端口465)或STARTTLS(端口587)
  • 开启两步验证的账号需使用应用专用密码
  • 发送频率和邮件内容需符合Gmail反垃圾政策

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 15:24:15