如何将邮件正文中img的cid格式src转换为真实图片路径?
将邮件正文中的CID格式图片地址转换为真实路径
问题场景
在邮件撰写(Message Compose)场景下,获取到的邮件正文中包含的图片标签src为CID格式,示例如下:
<img width="450" height="450" id="图片_x0020_2" src="cid:image002.jpg@01D9B4AD.403AFD90" /> <img width="465" height="467" id="图片_x0020_1" src="cid:image001.png@01D9B4AC.2C972DA0" />
已通过以下Office JS API代码获取草稿邮件内容:
Office.context.mailbox.item.saveAsync(function (result) { const itemId = result.value; Office.context.mailbox.getCallbackTokenAsync({ isRest: true }, (result) => { const token = result.value; const apiUrl = Office.context.mailbox.restUrl + "/v2.0/me/messages/" + itemId; axios .get(apiUrl, { headers: { Authorization: "Bearer " + token, }, }) .then((response) => { var draftData = response.data.Body.Content; console.log(draftData); }) .catch((error) => { console.log(error); }); }); });
需要将这些CID格式的src转换为可直接访问的真实图片路径。
解决方案
CID格式地址对应邮件的内嵌附件,需通过Graph API获取附件信息,匹配后生成可访问的图片地址,具体步骤如下:
1. 获取邮件的内嵌附件列表
在获取草稿邮件内容后,调用附件接口获取该邮件的所有附件,筛选出内嵌类型的附件:
const attachmentsUrl = Office.context.mailbox.restUrl + "/v2.0/me/messages/" + itemId + "/attachments"; axios.get(attachmentsUrl, { headers: { Authorization: "Bearer " + token } }) .then(attachmentsResponse => { const inlineAttachments = attachmentsResponse.data.value.filter(att => att.IsInline === true); // 后续匹配替换逻辑 });
2. 匹配CID与附件的ContentId
CID格式为cid:[contentId],截取cid:后的部分,与附件的ContentId字段匹配,生成可访问的图片地址:
// 替换HTML中的CID为真实图片地址 function replaceCidWithImageUrl(html, attachments) { return html.replace(/src="cid:([^"]+)"/g, (match, cid) => { const attachment = attachments.find(att => att.ContentId === cid); if (!attachment) return match; // 方案1:生成Base64 Data URL(无需额外请求,直接可用) const dataUrl = `data:${attachment.ContentType};base64,${attachment.ContentBytes}`; return `src="${dataUrl}"`; // 方案2:使用附件内容的直接访问URL(需保证token有效) // const attachmentUrl = `${Office.context.mailbox.restUrl}/v2.0/me/messages/${itemId}/attachments/${attachment.Id}/$value`; // return `src="${attachmentUrl}"`; }); }
3. 整合到原有代码中
修改后的完整代码示例:
Office.context.mailbox.item.saveAsync(function (result) { const itemId = result.value; Office.context.mailbox.getCallbackTokenAsync({ isRest: true }, (tokenResult) => { const token = tokenResult.value; const apiUrl = Office.context.mailbox.restUrl + "/v2.0/me/messages/" + itemId; const attachmentsUrl = Office.context.mailbox.restUrl + "/v2.0/me/messages/" + itemId + "/attachments"; // 并行获取邮件内容和附件 Promise.all([ axios.get(apiUrl, { headers: { Authorization: "Bearer " + token } }), axios.get(attachmentsUrl, { headers: { Authorization: "Bearer " + token } }) ]) .then(([mailResponse, attachmentsResponse]) => { const draftData = mailResponse.data.Body.Content; const inlineAttachments = attachmentsResponse.data.value.filter(att => att.IsInline === true); // 替换CID为真实图片地址 const updatedHtml = replaceCidWithImageUrl(draftData, inlineAttachments); console.log(updatedHtml); }) .catch((error) => { console.log(error); }); }); }); // 定义CID替换函数 function replaceCidWithImageUrl(html, attachments) { return html.replace(/src="cid:([^"]+)"/g, (match, cid) => { const attachment = attachments.find(att => att.ContentId === cid); if (!attachment) return match; return `src="data:${attachment.ContentType};base64,${attachment.ContentBytes}"`; }); }
内容的提问来源于stack exchange,提问作者teleixi
相关产品推荐
相关产品推荐

