使用Indy 10和DELPHI评估电子邮件 [英] Evaluate Email with Indy 10 and DELPHI
问题描述
我使用以下代码评估味精。用INDY 10组件接收的电子邮件消息的内容的内容(正文/行)
I use the following code to eval the msg. content (body / lines) of an E Mail msg received with the INDY 10 components
function LinesFromMsg(aMsg: TIdMessage): TStrings;
var
i: Integer;
begin
for i := 0 to aMsg.MessageParts.AttachmentCount-1 do
begin
if (amsg.MessageParts.Items[i].ContentType ='HTML') then
begin
if (amsg.MessageParts.Items[i] is Tidtext) then
Result := TidText(amsg.MessageParts.Items[i]).body;
end;
end;
end;
关于此代码,我有2个问题:
regarding this code I have 2 questions :
a)这是在arbitray邮件中查找Tlines部分的正确方法吗?
(请考虑显示10封电子邮件味精零件)
a) is this the correct way of finding the Tlines part in an arbitray mail message ? ( consider the advice shown at INDY 10 EMAIL MSG PARTS )
b)在哪里可以找到有关所有不同Contenttype字符串值的教程?
b) where can I find a tutorial of all the different Contenttype string values?
推荐答案
要查找的正确 ContentType
值是 text / html
。使用Indy的 IsHeaderMediaType()
函数进行检查,因为 ContentType
值可能具有与之相关的其他属性,您可以进行比较需要忽略。
The correct ContentType
value to look for is text/html
. Use Indy's IsHeaderMediaType()
function to check it, as the ContentType
value may have additional attributes associated with it that your comparison needs to ignore.
您还需要考虑 TIdMessage.ContentType
,因为HTML电子邮件可能
You also need to take the TIdMessage.ContentType
into account as well, as HTML emails may not be MIME encoded and thus not use the TIdMessage.MessageParts` collection at all.
最后,您需要使用 MessageParts.Count来对MIME进行编码,因此根本不使用TIdMessage.MessageParts`集合。
属性而不是 MessageParts.AttachmentsCount
属性。
And lastly, you loop needs to use the MessageParts.Count
property instead of the MessageParts.AttachmentsCount
property.
尝试以下操作:
function HTMLFromMsg(aMsg: TIdMessage): TStrings;
var
i: Integer;
Part: TIdMessagePart;
begin
Result := nil;
if IsHeaderMediaType(aMsg.ContentType, 'text/html') then
begin
Result := aMsg.Body;
Exit;
end;
for i := 0 to aMsg.MessageParts.Count-1 do
begin
Part := aMsg.MessageParts.Items[i];
if (Part is TIdText) and IsHeaderMediaType(Part.ContentType, 'text/html') then
begin
Result := TIdText(Part).Body;
Exit;
end;
end;
end;
话虽如此,从技术上讲,这不是处理MIME的正确方法。正式地,一个合规的阅读器应该从MIME部分向后循环,因为它们是从最简单的形式到最复杂的形式排列的。因此,您可以向后循环,考虑到MIME嵌套,寻找您支持的最复杂的形式。像这样(未经测试):
With that said, this is technically not the correct way to handle MIME. Officially, a conforming reader is supposed to loop backwards through the MIME parts, as they are ordered from the simpliest form downwards towards the most complex form. So you loop backwards, taking MIME nesting into account, looking for the most complex form you support. Something more like this (untested):
procedure DisplayPlainText(Body: TStrings);
begin
// display plain text as needed...
end;
procedure DisplayHTML(Body: TStrings);
begin
// display html as needed...
end;
procedure DisplayMultiPartAlternative(aMsg: TIdMessage; aParentIndex, aLastIndex: Integer);
var
Part: TIdMessagePart;
i: Integer:
begin
for i := aLastIndex-1 downto aParentIndex+1 do
begin
Part := aMsg.MessageParts.Items[i];
if (Part.ParentPart = aParentIndex) and (Part is TIdText) then
begin
if IsHeaderMediaType(Part.ContentType, 'text/html') then
begin
DisplayHTML(TIdText(Part).Body);
Exit;
end;
if IsHeaderMediaType(Part.ContentType, 'text/plain') then
begin
DisplayPlainText(TIdText(Part).Body);
Exit;
end;
end;
end;
// nothing supported to display...
end;
procedure DisplayMultiPartMixed(aMsg: TIdMessage; aParentIndex, aLastIndex: Integer);
var
Part: TIdMessagePart;
i: Integer;
begin
for i := aLastIndex-1 downto aParentIndex+1 do
begin
Part := aMsg.MessageParts.Items[i];
if (Part.ParentPart = aParentIndex) and (Part is TIdText) then
begin
if IsHeaderMediaType(Part.ContentType, 'multipart/alternative') then
begin
DisplayMultiPartAlternative(aMsg, ParentPart.Index, aLastIndex);
Exit;
end;
if IsHeaderMediaType(ParentPart.ContentType, 'text/html') then
begin
DisplayHTML(TIdText(Part).Body);
Exit;
end;
if IsHeaderMediaType(Part.ContentType, 'text/plain') then
begin
DisplayPlainText(TIdText(Part).Body);
Exit;
end;
aLastIndex := i;
end;
end;
// nothing supported to display...
end;
procedure DisplayMsg(aMsg: TIdMessage);
var
ContentType: string;
begin
ContentType := ExtractHeaderMediaType(aMsg.ContentType);
case PosInStrArray(ContentType, ['multipart/mixed', 'multipart/alternative', 'text/html', 'text/plain'], False) of
0: begin
DisplayMultiPartAlternative(aMsg, -1, aMsg.MessageParts.Count);
Exit;
end;
1: begin
DisplayMultiPartMixed(aMsg, -1, aMsg.MessageParts.Count);
Exit;
end;
2: begin
DisplayHTML(aMsg.Body);
Exit;
end;
3: begin
DisplayPlainText(aMsg.Body);
Exit;
end;
else
// nothing supported to display...
end;
end;
这篇关于使用Indy 10和DELPHI评估电子邮件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!