移动端Outlook插件中替代不支持的getAsFileAsync函数获取Base64格式邮件的可行方案(无需Azure令牌)
移动端Outlook插件中替代不支持的getAsFileAsync函数获取Base64格式邮件的可行方案(无需Azure令牌)
我太懂你现在的处境了——桌面端用Office.context.mailbox.item.getAsFileAsync一键把邮件转成Base64的EML文件,别提多顺手了,结果到了移动端这个函数直接失效,还要绕开麻烦的Azure令牌流程,确实头疼。
别慌,咱们可以换个思路:既然getAsFileAsync本质是返回标准EML格式的Base64内容,那我们完全可以用移动端支持的Outlook插件API手动拼凑出EML文件,再转成Base64,全程不需要Azure令牌。
具体实现步骤
下面是一步步的操作思路和示例代码:
1. 收集邮件的核心元数据
先通过移动端支持的属性获取邮件的基础信息:
// 获取主题 const subject = Office.context.mailbox.item.subject; // 获取发件人 const from = Office.context.mailbox.item.from; // 获取收件人、抄送人 const toRecipients = Office.context.mailbox.item.to; const ccRecipients = Office.context.mailbox.item.cc || []; // 获取邮件发送日期(用item的dateReceived或当前时间兜底) const date = Office.context.mailbox.item.dateReceived?.toUTCString() || new Date().toUTCString();
2. 获取邮件正文
用body.getAsync获取HTML格式的正文(移动端完全支持):
Office.context.mailbox.item.body.getAsync(Office.CoercionType.Html, (asyncResult) => { if (asyncResult.status === Office.AsyncResultStatus.Failed) { console.error(`获取正文失败: ${asyncResult.error.message}`); return; } const bodyHtml = asyncResult.value; // 拿到正文后继续处理附件和组装逻辑 });
3. 获取附件内容
用getAttachmentsAsync和getAttachmentContentAsync获取所有附件的Base64内容:
Office.context.mailbox.item.getAttachmentsAsync((asyncResult) => { if (asyncResult.status === Office.AsyncResultStatus.Failed) { console.error(`获取附件列表失败: ${asyncResult.error.message}`); return; } const attachments = asyncResult.value; // 用Promise批量获取附件内容 const attachmentPromises = attachments.map(att => { return new Promise((resolve, reject) => { Office.context.mailbox.item.getAttachmentContentAsync(att.id, (attResult) => { if (attResult.status === Office.AsyncResultStatus.Failed) { reject(attResult.error.message); return; } resolve({ name: att.name, contentType: att.contentType, content: attResult.value.content }); }); }); }); Promise.all(attachmentPromises).then(attachmentsContent => { // 拿到所有附件内容后,开始组装EML }).catch(err => { console.error(`获取附件内容失败: ${err}`); }); });
4. 手动组装EML格式
按照RFC 5322标准拼接邮件头、正文和附件,这里给一个简化的示例(复杂场景如内嵌图片可扩展MIME嵌套结构):
function buildEML(subject, from, to, cc, date, bodyHtml, attachments) { // 生成随机MIME边界 const boundary = `----=_NextPart_${Date.now().toString(16)}`; let eml = ''; // 邮件头部分 eml += `From: "${from.displayName}" <${from.emailAddress}>\r\n`; eml += `To: ${to.map(recp => `"${recp.displayName}" <${recp.emailAddress}>`).join(', ')}\r\n`; if (cc.length > 0) { eml += `Cc: ${cc.map(recp => `"${recp.displayName}" <${recp.emailAddress}>`).join(', ')}\r\n`; } eml += `Subject: ${subject}\r\n`; eml += `Date: ${date}\r\n`; eml += `MIME-Version: 1.0\r\n`; eml += `Content-Type: multipart/mixed; boundary="${boundary}"\r\n\r\n`; // 正文部分 eml += `--${boundary}\r\n`; eml += `Content-Type: text/html; charset="UTF-8"\r\n`; eml += `Content-Transfer-Encoding: base64\r\n\r\n`; eml += btoa(unescape(encodeURIComponent(bodyHtml))) + '\r\n\r\n'; // 附件部分 attachments.forEach(att => { eml += `--${boundary}\r\n`; eml += `Content-Type: ${att.contentType}\r\n`; eml += `Content-Disposition: attachment; filename="${att.name}"\r\n`; eml += `Content-Transfer-Encoding: base64\r\n\r\n`; eml += att.content + '\r\n\r\n'; }); // 结束边界 eml += `--${boundary}--\r\n`; return eml; }
5. 转成Base64编码
把组装好的EML字符串转成Base64,就和getAsFileAsync返回的结果一致了:
const emlString = buildEML(subject, from, toRecipients, ccRecipients, date, bodyHtml, attachmentsContent); const emlBase64 = btoa(unescape(encodeURIComponent(emlString))); // 这里的emlBase64就是你需要的最终结果
注意事项
- 上面的EML组装是基础场景版本,若要处理带内嵌图片的HTML邮件、特殊编码内容,需要额外扩展MIME的嵌套结构,但日常使用完全够用。
- 所有用到的API都是移动端Outlook插件官方支持的,兼容性没问题。
备注:内容来源于stack exchange,提问作者DavidDunham
相关产品推荐
相关产品推荐

