使用PHP Gmail API发带附件邮件时内容变noname.html附件的解决方法
解决Gmail API发送邮件时正文变成noname.html附件的问题
嘿,我之前踩过这个一模一样的坑!这大概率是因为你没正确设置邮件的MIME结构和Content-Type头,导致Gmail API把你的正文误判成了附件。咱们一步步来修复:
核心原因
Gmail API要求邮件内容必须是完整的MIME格式(包含正确的邮件头和正文),并且要编码成base64url格式。如果缺少必要的Content-Type声明,或者编码方式不对,就会出现正文被当作附件的情况。
解决方案:构造正确的MIME邮件并编码
下面是修正后的完整代码示例,直接替换你原来的邮件构造部分即可:
$client->setAccessToken($_SESSION['gmail_access_token']); $objGMail = new Google_Service_Gmail($client); // 1. 设置邮件基础信息 $to = '收件人邮箱@example.com'; $from = '你的邮箱@example.com'; $subject = '测试邮件(通过Gmail API发送)'; // 2. 你的HTML正文内容 $strMailContent = 'This is a test mail which is <b>sent via</b> using Gmail API client library.<br/>这是换行测试内容。'; // 3. 构造完整的MIME格式邮件(包含所有必要头信息) $rawMessage = "From: $from\r\n"; $rawMessage .= "To: $to\r\n"; // 主题要处理UTF-8编码,避免乱码 $rawMessage .= "Subject: =?UTF-8?B?" . base64_encode($subject) . "?=\r\n"; $rawMessage .= "MIME-Version: 1.0\r\n"; // 关键:明确声明内容类型为text/html $rawMessage .= "Content-Type: text/html; charset=utf-8\r\n\r\n"; $rawMessage .= $strMailContent; // 4. 编码成Gmail API要求的base64url格式 $encodedMessage = rtrim(strtr(base64_encode($rawMessage), '+/', '-_'), '='); // 5. 创建并发送邮件 $message = new Google_Service_Gmail_Message(); $message->setRaw($encodedMessage); try { $objGMail->users_messages->send('me', $message); echo "邮件发送成功!"; } catch (Exception $e) { echo "发送失败:" . $e->getMessage(); }
进阶:同时支持HTML和纯文本(避免客户端不兼容)
如果要让不支持HTML的邮件客户端也能正常显示,可以构造multipart/alternative类型的邮件,这样正文不会被当成附件,还能适配不同客户端:
// 构造多部分邮件的边界标识 $boundary = uniqid(); $rawMessage = "From: $from\r\n"; $rawMessage .= "To: $to\r\n"; $rawMessage .= "Subject: =?UTF-8?B?" . base64_encode($subject) . "?=\r\n"; $rawMessage .= "MIME-Version: 1.0\r\n"; $rawMessage .= "Content-Type: multipart/alternative; boundary=\"$boundary\"\r\n\r\n"; // 纯文本部分(给不支持HTML的客户端) $rawMessage .= "--$boundary\r\n"; $rawMessage .= "Content-Type: text/plain; charset=utf-8\r\n\r\n"; $rawMessage .= strip_tags($strMailContent) . "\r\n\r\n"; // HTML部分 $rawMessage .= "--$boundary\r\n"; $rawMessage .= "Content-Type: text/html; charset=utf-8\r\n\r\n"; $rawMessage .= $strMailContent . "\r\n\r\n"; // 结束边界 $rawMessage .= "--$boundary--"; // 后续编码和发送步骤和上面一致...
关键注意点
- 一定要确保
Content-Type头正确设置:纯文本用text/plain,HTML用text/html,多部分用multipart/alternative。 - 邮件主题如果包含中文或特殊字符,必须用base64编码(示例中的
=?UTF-8?B?...?=格式),避免乱码。 - 编码时必须用
base64url格式(替换+为-,/为_,去掉末尾的=),这是Gmail API的强制要求。
内容的提问来源于stack exchange,提问作者Premjith
相关产品推荐
相关产品推荐

