消息是结构化的(当然是强烈删节版本):
Content-Type: multipart/mixed; boundary="----=_Part_853547_18414509.1354745829993" <some irrelevant header stuff> ------=_Part_853547_18414509.1354745829993 Content-Type: multipart/alternative; boundary="----=_Part_853548_20128671.1354745829993" ------=_Part_853548_20128671.1354745829993 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <the message in plain text> ------=_Part_853548_20128671.1354745829993 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <the message in HTML> ------=_Part_853548_20128671.1354745829993-- ------=_Part_853547_18414509.1354745829993--
现在,当我表演时
imap.UIDRetrieve(UID,Msg)
然后
Msg.ContentType = "multipart/mixed"
并且单个Msg.MessageParts将此作为content-type:
Msg.MessageParts[0].ContentType = "multipart/alternative; boundary="----=_Part_853548_20128671.1354745829993"" Msg.MessageParts[1].ContentType = "text/plain"
没有文字/ html部分的痕迹.
有人会知道这里发生了什么吗?
(我正在使用最新的Indy版本)
当我使用当前的Indy 10 SVN快照直接通过TIdMessage运行该电子邮件数据时,它解析得很好.生成三个MessageParts条目 – multipart / alternative,text / plain和text / html – 正如预期的那样.在your recent post to the Embarcadero forum关于同一主题,您遗漏了一条关键信息 – 您正在使用TIdIMAP4来检索失败的电子邮件.这一点很重要,因为您认为不相关的电子邮件部分必须包含一个Indy代码的数据,该代码具有已知的设计限制,不会在Indy 10中修复(但已经标记为Indy 11的要求)但这会影响TIdIMAP4.
在内部,TIdIMAP4.UIDRetreive()按原样将原始下载的电子邮件传递给TIdMessage.LoadFromStream(). TIdMessage内部的核心解析器期望使用IMAP实际上不使用的SMTP样式的点透明度来转义输入数据. TIdMessage目前无法知道输入电子邮件数据的来源,因此无法了解转发数据的格式.更高级别的协议传输负责根据需要解析和解码转义数据,然后将未转义的数据传递给TIdMessage以进行进一步解析.但现在情况并非如此. Indy 10中的逻辑分离并没有达到应有的程度. TIdMessage使用对源数据的直接访问,这在TIdSMTP和TIdPOP3中工作正常,但在TIdIMAP4中没有.
在IdMessageClient.pas单元中,有一个名为TIdIOHandlerStreamMsg的辅助类,它具有公共EscapeLines属性,专门用于在需要它的情况下帮助解决此问题(即,将未转义的数据传递给TIdMessage.LoadFrom …( ) 方法).当前的解决方法是实例化TIdMessageClient,将TIdIOHandlerStreamMsg分配给其IOHandler属性,将其EscapeLines属性设置为True,并将源TStream传递给解析和目标TIdMessage以输出到,而不是直接调用TIdMessage.LoadFromStream().这允许Indy伪造核心解析器期望无法转换的转义格式.
但是,TIdIMAP4目前尚未使用此解决方法.现在我想到这一点,它应该很容易添加,所以我会调查它.在此期间,您可以使用TIdIMAP4.RetrieveNoDecodeToStream()或TIdIMAP4.UIDRetrieveNoDecodeToStream(),它将在写入目标TStream时间接转义数据(另一个需要修复的已知设计限制),然后您可以将该TStream传递给TIdMessage .LoadFromStream()正常解析.
更新:我刚刚检查了TIdIMAP4的AppendMsg()和InternalRetrieve()方法的更新,不再依赖于SMTP样式的点透明度.这已经在Indy的TODO列表上已经有好几年了,所以很高兴最终解决它.