AWS Lambda发送UTF-8邮件:雅虎邮箱无法解码内容问题
我来帮你排查这个问题——你遇到的核心问题是Yahoo邮箱没有正确识别邮件的UTF-8编码,虽然你在AWS JavaScript SDK里指定了Charset: "UTF-8",但邮件头里的Content-Type并没有带上charset=UTF-8字段,导致Yahoo用默认编码解析,把quoted-printable格式的UTF-8内容直接显示出来了。
下面给你几个可行的解决方案:
1. 升级AWS SDK for JavaScript版本
旧版本的AWS SES SDK(比如v2的某些早期版本)在处理Charset参数时偶尔会有bug,导致无法正确生成带charset=UTF-8的Content-Type头。建议升级到最新的AWS SDK for JavaScript v3,它在SES的参数处理上更严谨,大部分情况下能自动解决这个问题。
升级后你的原有代码应该就能正常工作,不需要做太多修改——只要确保Body.Html.Charset、Body.Text.Charset和Subject.Charset都明确设置为"UTF-8"即可。
2. 改用sendRawEmail手动构造MIME消息
如果升级SDK后问题依然存在,那可以直接用sendRawEmail API发送完整的MIME邮件,这样你能完全控制所有邮件头,确保Content-Type符合预期。
示例代码如下:
const AWS = require('aws-sdk'); const ses = new AWS.SES({ region: '你的AWS区域,比如us-east-1' }); // 配置邮件基本信息 const domain_name = 'your-domain.com'; const toEmail = 'dummy@email.co'; const fromEmail = `aws@${domain_name}`; const replyToEmail = 'dummy@email.co'; const subject = `New email from ${domain_name}`; const messageHtml = '<p>这里是你的UTF-8内容,比如包含中文、特殊字符:测试🎯</p>'; // 构造MIME边界 const boundary = `----=_NextPart_${Date.now()}`; // 组装原始MIME消息 const rawEmailContent = [ `From: ${fromEmail}`, `To: ${toEmail}`, `Reply-To: ${replyToEmail}`, // 主题用base64编码确保UTF-8显示正常 `Subject: =?UTF-8?B?${Buffer.from(subject).toString('base64')}?=`, 'MIME-Version: 1.0', `Content-Type: multipart/alternative; boundary="${boundary}"`, '', // 纯文本部分 `--${boundary}`, 'Content-Type: text/plain; charset=UTF-8', 'Content-Transfer-Encoding: quoted-printable', '', Buffer.from(messageHtml.replace(/<[^>]+>/g, '')).toString('base64'), '', // HTML部分 `--${boundary}`, 'Content-Type: text/html; charset=UTF-8', 'Content-Transfer-Encoding: quoted-printable', '', Buffer.from(messageHtml).toString('base64'), '', `--${boundary}--` ].join('\r\n'); // 发送邮件参数 const params = { RawMessage: { Data: Buffer.from(rawEmailContent).toString('base64') } }; // 调用SES发送邮件 ses.sendRawEmail(params, (err, data) => { if (err) { console.error('发送失败:', err); } else { console.log('发送成功:', data); } });
这个方法的核心是手动定义了Content-Type: text/html; charset=UTF-8和Content-Transfer-Encoding: quoted-printable头,Yahoo邮箱会严格按照这个配置解析邮件内容,不会再出现编码问题。
3. 检查邮件内容是否被提前编码
最后确认下你的message变量是否已经是经过quoted-printable或base64编码的字符串。如果message已经被编码,SES可能不会再为它添加charset字段,导致Yahoo无法识别编码格式。确保message是原始的UTF-8字符串,让SES来处理编码和头信息的生成。
内容的提问来源于stack exchange,提问作者Charles Saag

