Gmail API Node.js客户端发送邮件时正文转为附件问题求助
问题根因
你遇到的正文被自动判定为附件的问题,全部来自手写MIME邮件结构时的语法错误,和OAuth授权、接口调用流程无关:
- 核心错误:原代码中
Content-Type头行缺失参数分隔符。你写的是Content-Type: text/html charset=utf-8,按照MIME规范,主类型和参数之间必须用分号分隔,正确写法是Content-Type: text/html; charset=utf-8。
这个标点缺失会直接导致邮件解析器识别不到合法的内容类型标识,会把无合法内联属性的内容自动归类为无类型附件,最终呈现的效果就是你传入的text内容被生成了.html后缀的附件,没有正常内联展示。 - 兼容优化点:目前代码用
\n做行分隔,虽然Gmail自身的解析器多数场景下可以兼容,但严格遵循邮件传输规范的链路要求用\r\n作为行分隔符,非规范的换行在部分邮件网关的解析逻辑里,也可能触发异常把正文判定为附件。
修正后的可运行代码
import {google} from 'googleapis' const accessToken = '通过Google OAuth2流程获取的有效访问令牌' async function sendMail(subject: string, text: string, to: string, from: string) { const utf8Subject = `=?utf-8?B?${Buffer.from(subject).toString('base64')}?=` const messageParts = [ `From: ${from}`, `To: ${to}`, // 修正Content-Type语法错误,补上参数分隔分号 'Content-Type: text/html; charset=utf-8', 'MIME-Version: 1.0', `Subject: ${utf8Subject}`, '', text, ] // 用规范的CRLF做行分隔,提升全链路兼容性 const message = messageParts.join('\r\n') const encodedMessage = Buffer.from(message) .toString('base64') // 适配Gmail要求的URL安全Base64编码 .replace(/\+/g, '-') .replace(/\//g, '_') .replace(/=+$/, '') const gmail = google.gmail({version: 'v1', auth: accessToken}) await gmail.users.messages.send({ userId: 'me', requestBody: { raw: encodedMessage, } }) } sendMail('测试主题', '<p>这是可以正常内联展示的HTML正文</p>', '收件人@example.com', '发件人@example.com')
注意事项:手写单部分MIME邮件时,只需要在头字段正确标注Content-Type、空行之后直接写正文内容即可,不需要额外添加
Body:、HTML:这类自定义标签——这类标签不属于标准MIME结构,加了反而会破坏解析逻辑。
内容的提问来源于stack exchange,提问作者Iago Mendes
相关产品推荐
相关产品推荐

