Outlook插件中img标签与内嵌附件的关联匹配问题
Outlook插件:匹配cid格式img标签与对应内嵌附件
问题描述
开发Outlook插件时,通过Office.context.mailbox.item.attachments提取邮件HTML内容正常,但遇到内嵌图片的问题:邮件HTML中的img标签src为cid格式(如下示例),虽然能识别isInline为true的附件并提取其Base64内容,但无法关联img标签和对应附件。
示例cid格式img标签:
<img class="x_w-1378 x_h-886" size="349452" data-outlook-trace="F:1|T:1" src="cid:9ea35d14-aa1e-47d6-9c5b-b31ced143981" style="max-width:100%"> <img width="643" height="359" id="x_Picture_x0020_1" src="cid:image001.png@01D8A327.B5A0B590" style="width:6.6979in; height:3.7395in">
解决方案
核心是利用附件的contentId属性进行匹配——img标签src中cid:后的内容,就是对应内嵌附件的contentId值。具体步骤如下:
1. 收集内嵌附件的contentId与Base64映射
遍历所有邮件附件,筛选出isInline: true的内嵌附件,构建一个以contentId为键、Base64内容和文件类型为值的映射表:
const inlineAttachmentsMap = new Map(); const attachments = Office.context.mailbox.item.attachments; // 用Promise封装异步操作,保证映射表构建完成后再处理HTML const buildAttachmentMap = () => { const promises = []; for (let i = 0; i < attachments.length; i++) { const attachment = attachments[i]; if (attachment.isInline) { const promise = new Promise((resolve) => { attachment.getContentAsync(Office.CoercionType.Base64, (result) => { if (result.status === Office.AsyncResultStatus.Succeeded) { inlineAttachmentsMap.set(attachment.contentId, { base64: result.value, contentType: attachment.contentType }); } resolve(); }); }); promises.push(promise); } } return Promise.all(promises); };
2. 解析HTML并匹配替换img标签
待附件映射表构建完成后,解析邮件HTML内容,提取所有src为cid:开头的img标签,截取cid:后的字符串作为目标contentId,再从映射表中找到对应附件,替换img的src为Base64格式的Data URL:
// 获取邮件HTML并处理 buildAttachmentMap().then(() => { Office.context.mailbox.item.body.getAsync(Office.CoercionType.Html, (result) => { if (result.status === Office.AsyncResultStatus.Succeeded) { let processedHtml = result.value; // 匹配所有cid格式的img标签 const cidImgRegex = /<img[^>]+src="cid:([^"]+)"/g; processedHtml = processedHtml.replace(cidImgRegex, (match, contentId) => { const attachmentInfo = inlineAttachmentsMap.get(contentId); if (attachmentInfo) { // 替换为Data URL return match.replace(`cid:${contentId}`, `data:${attachmentInfo.contentType};base64,${attachmentInfo.base64}`); } // 未匹配到则保留原src return match; }); // 处理后的HTML即可正常显示内嵌图片 console.log(processedHtml); } }); });
注意事项
- 精确匹配contentId:cid后的字符串需与附件的
contentId完全一致,包括@后缀的部分(如示例中的image001.png@01D8A327.B5A0B590)。 - 异步顺序处理:由于
getContentAsync是异步操作,必须保证附件映射表构建完成后再处理HTML,避免匹配失败。 - contentType校验:利用附件的
contentType生成正确的Data URL,确保图片能正常渲染。
内容的提问来源于stack exchange,提问作者R. Mohammad
相关产品推荐
相关产品推荐

