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

如何通过Microsoft Graph API获取附件原始内容并解决编码上传异常

Microsoft Graph API 文件附件获取编码异常、上传损坏问题处理

问题现象

  • 调用Graph接口获取邮件文件附件时,返回内容字节存在编码异常,和Notepad++打开的原文件内容完全不匹配,原文件二进制内容片段如下:
UÏMÌØˆ€aX!D"AŠMtPïq¡ª†f24O]J¦¢’k¿ÇFcX+|¿¯÷q”z{CîËC~ãZVŸâÆù ´*ëáµå:ã/•þ57Yü*—kØ&Ž=NDüßÒLó>@÷.MÊ
×núšÙÄlsb´Ò·SFAÙá~˜ wpÌ&—wY¯ÇpÊúé(¯uïû°×Œ†ˆ÷.”ÒB1ŒKŽ|G;m««¼Õ‘h’IRLp°,µ‰<ÿ¥*‡ë>Ž´ÌÇRtA‰öjJäÂY<5&u„óNæÓÓ¿Md¡U§ÎkäÐÁJÛO{9’^¬C]Ó<ô;Ë:N“šK8KÏH1
  • 最初使用的附件获取代码返回内容格式完全错误,代码如下:
public function getRawAttachmentContents($emailAddress, $messageId)
{
    return $this->graph->createRequest("GET", "/users/$emailAddress/messages/$messageId/attachments/{attachmentId}")
        ->setReturnType(get_class(new \Microsoft\Graph\Model\FileAttachment()))
        ->execute();
}
  • 首次尝试在接口路径末尾追加$value获取原始二进制内容时,接口无任何返回,返回情况截图:
    接口返回截图
  • 调整代码后可获取到和Notepad++打开显示完全一致的附件内容,但将返回内容上传至草稿邮件时,要么无法创建附件,要么接口返回201 Created响应但生成的附件损坏。可正确获取原始附件内容的代码如下:
public function getRawAttachmentContents($emailAddress, $messageId, $attachmentId)
{
    $attachment = $this->graph->createRequest("GET", "/users/$emailAddress/messages/$messageId/attachments/$attachmentId/\$value")
        ->execute();
    $attachment->getRawBody()->rewind();
    $file_contents = $attachment->getRawBody()->getContents();
    return $file_contents;
}

根因说明

  • 未加$value调用接口时,返回的是JSON结构的附件实体,其中文件内容是Base64编码的contentBytes字段,SDK绑定FileAttachment模型做反序列化时存在编码转换逻辑,会破坏原始二进制字节,导致内容和原文件不一致。
  • 初次调用$value端点无返回,是因为该端点直接返回二进制流,不存在JSON结构化响应,不能通过绑定模型类的方式解析结果,必须直接读取响应的原始Body流。
  • 上传附件损坏的核心问题:创建文件附件的接口要求传入的contentBytes字段为Base64编码的文件内容,直接传入获取到的原始二进制流会导致内容解析错误;若上传时未正确填写附件MIME类型、原文件名,也会出现附件损坏的情况。

正确实现方案

  1. 附件获取环节直接使用上述调整后的流读取代码,拿到的$file_contents是原始正确的二进制字节,不要对该内容做任何编码转换、字符集修改操作,避免破坏文件结构。
  2. 上传附件到草稿邮件时,构造符合接口要求的请求体,对原始字节做Base64编码后传入,示例代码如下:
// 构造附件上传参数
$attachmentPayload = [
    "@odata.type" => "#microsoft.graph.fileAttachment",
    "name" => "原文件完整名称带后缀", // 例如 合同.pdf
    "contentType" => "文件对应的标准MIME类型", // 例如pdf对应application/pdf,docx对应application/vnd.openxmlformats-officedocument.wordprocessingml.document
    "contentBytes" => base64_encode($file_contents) // 必须对原始二进制内容做Base64编码
];
// 发起上传请求
$this->graph->createRequest("POST", "/users/{$emailAddress}/messages/{$draftMessageId}/attachments")
    ->attachBody($attachmentPayload)
    ->execute();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 00:36:19