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

使用Gmail API发送超5MB大附件遇“Entity too large”错误求解决

Fixing "Entity too large" Error When Sending Large Attachments (>5MB) via Gmail API with PHP Client Library

我之前在项目里也踩过一模一样的坑——照着官方文档和第三方教程操作,结果反复收到"Entity too large"错误,折腾了好一阵子才摸透问题的核心。下面是我亲测有效的解决方案,一步步帮你搞定:

核心前提:必须用可恢复上传(Resumable Upload)

Gmail API对超过5MB的附件强制要求使用可恢复上传模式,直接调用普通的messages.send接口传完整邮件内容肯定会触发报错。你需要先创建上传会话,分块上传附件,最后完成邮件发送流程。

PHP客户端库的正确代码流程

给你一份完整的可运行代码示例,我会拆解里面的关键细节:

<?php
require __DIR__ . '/vendor/autoload.php';

// 初始化已完成OAuth2认证的Gmail客户端(这里假设你已经搞定了授权流程)
$client = getYourAuthenticatedGmailClient(); // 替换成你的认证逻辑
$gmail = new Google\Service\Gmail($client);

// 1. 构建邮件基础MIME结构(先预留附件位置)
$boundary = uniqid('boundary_');
$rawMessage = <<<EOT
To: recipient@example.com
Subject: Test Large Attachment
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="$boundary"

--$boundary
Content-Type: text/plain; charset="UTF-8"

This is a test email with a large attachment.

--$boundary
Content-Type: application/pdf; name="large_file.pdf"
Content-Disposition: attachment; filename="large_file.pdf"
Content-Transfer-Encoding: base64

EOT;

// 2. 初始化可恢复上传会话
$message = new Google\Service\Gmail\Message();
$upload = new Google\Http\MediaFileUpload(
    $client,
    $gmail->users_messages->send('me', $message),
    'message/rfc822',
    null,
    true, // 关键:启用可恢复上传
    10485760 // 分块大小建议设为10MB,不要超过32MB的上限
);

// 计算完整邮件的总大小(基础MIME + 附件base64编码后的大小)
$filePath = '/path/to/your/large_file.pdf';
$fileSize = filesize($filePath);
$base64Size = ceil($fileSize * 4 / 3); // base64会增加约33%的体积
$totalSize = strlen($rawMessage) + $base64Size + strlen("\r\n--$boundary--");
$upload->setFileSize($totalSize);

// 3. 分块上传完整邮件内容
$fileHandle = fopen($filePath, 'rb');
// 先上传基础MIME部分
$status = $upload->nextChunk($rawMessage);
// 再分块上传附件的base64内容
while (!$status && !feof($fileHandle)) {
    $chunk = fread($fileHandle, 7864320); // 对应10MB原始文件的base64块(10MB*3/4=7.5MB)
    $status = $upload->nextChunk(base64_encode($chunk));
}
// 上传结尾的边界标记
$status = $upload->nextChunk("\r\n--$boundary--");

fclose($fileHandle);

// 4. 验证发送结果
if ($status) {
    echo "邮件发送成功!消息ID:" . $status->getId();
} else {
    echo "上传失败,请检查文件权限或网络连接";
}
?>

关键注意事项

  • 分块大小匹配:原始文件分块设为10MB时,base64编码后的块要对应约7.5MB(因为base64是3字节转4字节),避免单次上传的块超过API限制。
  • MIME结构严谨:边界标记必须前后一致,附件的Content-Type要和文件类型匹配,否则API会解析失败,误判为内容过大。
  • 权限检查:确保你的OAuth2令牌拥有https://www.googleapis.com/auth/gmail.send权限,且没有过期。
  • 文件权限:确认PHP进程能读取目标大文件,避免因文件读取失败导致上传中断。

排查"Entity too large"的常见坑

  • 你之前可能直接把包含大附件的完整raw字符串传给messages.send,这种方式只支持5MB以内的内容;
  • 初始化MediaFileUpload时没把resumable参数设为true,导致还是用了普通上传模式;
  • 邮件MIME结构错误(比如边界不闭合、附件编码错误),导致API解析时把损坏的内容判定为"过大"。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:13:39