AWS JS SDK调用SendRawEmail报Empty header names are illegal
问题根因定位
报错提到的空标头是SES服务端解析MIME内容时,因请求序列化异常识别到的无名称头(行首为冒号的异常行),并非构造MIME字符串时肉眼可见的显式空头,产生原因有三层:
- 核心触发原因:
RawMessage.Data字段传参类型不符合SDK要求。AWS JavaScript SDK v3的SendRawEmail接口规范中,RawMessage.Data要求传入Uint8Array/Buffer类型的二进制MIME内容,你直接传入了JS字符串。SDK在执行请求序列化、SigV4签名计算时,会默认将字符串按UTF-8规则转码,转码过程中会出现字节序列拆分错位,导致MIME头的换行、键值分隔符位置偏移,SES收到请求后解析MIME流时就会识别到空名称的头,抛出对应错误。 - 显性格式错误:你构造的MIME内容本身存在两处不规范问题,虽然不是本次空标头报错的直接诱因,但会导致发送成功后邮件显示异常:
- From头值错误使用了HTML转义字符
<、>,MIME头语法不需要做HTML转义,直接用尖括号<、>包裹邮箱地址即可,当前写法会导致收件人看到的发件人显示为带转义字符的异常文本。 - 声明了
Content-Transfer-Encoding: base64传输编码,但正文直接传入明文hello world,未做base64编码,会导致正文解析乱码。
- From头值错误使用了HTML转义字符
- 规范缺失问题:使用的
mimemessage库默认不会自动添加MIME协议必填的MIME-Version: 1.0头,缺少该头可能触发SES的MIME格式校验拦截,也会导致部分邮件客户端无法正常解析邮件。
修复方案
直接按以下步骤调整代码即可:
- 给MIME消息补充必填的
MIME-Version头 - 修正From头的写法,去掉HTML转义字符,直接使用原生尖括号包裹邮箱
- 短文本正文建议直接使用
8bit传输编码,省去base64编码步骤,降低格式错误概率;如果必须用base64,需要先将正文内容转成base64字符串再赋值 - 生成MIME字符串后,将其转为
Buffer类型再传入RawMessage.Data字段,禁止直接传字符串
修复后的可运行代码示例:
const { SESClient, SendRawEmailCommand } = require("@aws-sdk/client-ses"); const mimemessage = require("mimemessage"); const client = new SESClient({ region: "你的SES区域" }); const destination = "ilia.reingold@gmail.com"; // 构造MIME消息 const msg = mimemessage.factory({ contentType: 'text/plain; charset=utf-8', contentTransferEncoding: '8bit', body: 'hello world' }); // 添加必填头 msg.header('MIME-Version', '1.0'); msg.header('From', 'Admin <hello@condobeaver.com>'); msg.header('To', destination); msg.header('Subject', 'Customer service contact info'); const mimeContent = msg.toString(); // 调试时可打印确认MIME结构无异常 // console.log(mimeContent); const command = new SendRawEmailCommand({ Destinations: [destination], Source: 'hello@condobeaver.com', // 关键修复:转成Buffer类型传入 RawMessage: { Data: Buffer.from(mimeContent, 'utf-8') } }); const response = await client.send(command); console.log("邮件发送成功", response.MessageId);
修复后可先打印mimeContent确认结构,正确的MIME头区域无空行、无行首为冒号的异常行,头和正文之间用一个空行分隔即可。
内容的提问来源于stack exchange,提问作者ilrein
相关产品推荐
相关产品推荐

