【问题标题】:Evaluate Email with Indy 10 and DELPHI使用 Indy 10 和 DELPHI 评估电子邮件
【发布时间】:2013-02-03 09:16:24
【问题描述】:

我使用以下代码来评估味精。使用 INDY 10 组件接收的电子邮件消息的内容(正文/行)

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 个问题:

a) 这是在任意邮件消息中找到 Tlines 部分的正确方法吗? (考虑INDY 10 EMAIL MSG PARTS 上显示的建议)

b) 在哪里可以找到所有不同 Contenttype 字符串值的教程?

【问题讨论】:

    标签: delphi indy


    【解决方案1】:

    要查找的正确ContentType 值是text/html。使用 Indy 的 IsHeaderMediaType() 函数对其进行检查,因为 ContentType 值可能具有与之相关的其他属性,您的比较需要忽略这些属性。

    您还需要考虑TIdMessage.ContentType,因为 HTML 电子邮件可能没有经过 MIME 编码,因此根本不使用 TIdMessage.MessageParts` 集合。

    最后,您的循环需要使用MessageParts.Count 属性而不是MessageParts.AttachmentsCount 属性。

    试试这个:

    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 嵌套,寻找你支持的最复杂的形式。更像这样的东西(未经测试):

    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;
    

    【讨论】:

    • 和 IdMessageParts
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-08
    • 2015-10-24
    • 1970-01-01
    相关资源
    最近更新 更多