使用JS调用EWS在Outlook中发邮件时附件丢失及邮件入垃圾箱问题求解
附件无法发送问题修复
你的代码存在三处核心错误导致附件无法正常携带:
- SOAP请求结构不合法:不允许在单次SOAP请求的Body节点中同时包含
CreateItem和CreateAttachment两个操作,Exchange会直接忽略第二个操作的内容 - 自定义ItemId无效:你手动填写的
ItemId Id="123"是无效的虚拟ID,无法关联到实际生成的邮件草稿 - 操作顺序错误:发送带附件的邮件需要遵循三步流程:先创建草稿邮件获取真实ID→用真实ID上传附件→最后发送邮件
你可以按照如下逻辑修改代码:
function send_mail(msg) { // 第一步:创建草稿邮件,仅保存不发送 const createDraftRequest = `<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Header><t:RequestServerVersion Version="Exchange2010" /></soap:Header> <soap:Body> <m:CreateItem MessageDisposition="SaveOnly"> <m:SavedItemFolderId><t:DistinguishedFolderId Id="drafts" /></m:SavedItemFolderId> <m:Items> <t:Message> <t:Subject>${msg.subject}</t:Subject> <t:Body BodyType="HTML">${msg.body}</t:Body> <t:ToRecipients> <t:Mailbox><t:EmailAddress>${msg.To}</t:EmailAddress></t:Mailbox> </t:ToRecipients> </t:Message> </m:Items> </m:CreateItem> </soap:Body> </soap:Envelope>`; Office.context.mailbox.makeEwsRequestAsync(createDraftRequest, (draftResult) => { if (draftResult.status === "failed") { console.log("创建草稿失败:" + draftResult.error.message); return; } // 解析返回的真实草稿ID const parser = new DOMParser(); const xmlDoc = parser.parseFromString(draftResult.value, "text/xml"); const itemId = xmlDoc.getElementsByTagName("t:ItemId")[0].getAttribute("Id"); const changeKey = xmlDoc.getElementsByTagName("t:ItemId")[0].getAttribute("ChangeKey"); // 第二步:上传附件到草稿 const uploadAttachmentRequest = `<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Header><t:RequestServerVersion Version="Exchange2010" /></soap:Header> <soap:Body> <m:CreateAttachment> <m:ParentItemId Id="${itemId}" ChangeKey="${changeKey}"/> <m:Attachments> <!-- 普通文件附件使用FileAttachment节点,Content为文件的Base64编码 --> <t:FileAttachment> <t:Name>测试附件.txt</t:Name> <t:Content>aGVsbG8gd29ybGQ=</t:Content> </t:FileAttachment> </m:Attachments> </m:CreateAttachment> </soap:Body> </soap:Envelope>`; Office.context.mailbox.makeEwsRequestAsync(uploadAttachmentRequest, (attachResult) => { if (attachResult.status === "failed") { console.log("上传附件失败:" + attachResult.error.message); return; } // 第三步:发送带附件的邮件 const sendRequest = `<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Header><t:RequestServerVersion Version="Exchange2010" /></soap:Header> <soap:Body> <m:SendItem SaveItemToFolder="true"> <m:ItemIds> <t:ItemId Id="${itemId}" ChangeKey="${changeKey}"/> </m:ItemIds> <m:SavedItemFolderId> <t:DistinguishedFolderId Id="sentitems" /> </m:SavedItemFolderId> </m:SendItem> </soap:Body> </soap:Envelope>`; Office.context.mailbox.makeEwsRequestAsync(sendRequest, (sendResult) => { if (sendResult.status === "failed") { console.log("发送邮件失败:" + sendResult.error.message); } else { console.log("带附件的邮件发送成功"); } }); }); }); }
避免邮件进入垃圾邮件的配置方案
你可以从以下几个维度调整,降低被判定为垃圾邮件的概率:
- 发件人域名需配置完整的SPF、DKIM、DMARC解析记录,验证发送权限的合法性
- 邮件正文避免使用大量营销类、诱导类敏感词汇,HTML结构要规范,不要插入过多外部链接、隐藏样式
- 附件不要使用.exe、.bat等可执行后缀,如必须发送可压缩后标注安全说明,附件命名不要包含违规敏感词
- 不要短时间内向大量陌生收件人发送相同内容的邮件,避免触发批量发送垃圾邮件的判定规则
内容的提问来源于stack exchange,提问作者Suyash Srivastava
相关产品推荐
相关产品推荐

