使用 Indy 组件的最大消息长度

Maximum length of message using Indy components

我正在尝试从 delphi 发送消息 - 代码使用 TIdMessage。该消息由两部分组成:text/plaintext/html。 我有 html-page 作为模板和一些需要插入模板的大文本(在标记为 ##text## 的特殊位置)。合并模板和文本后,我得到了新消息的正文。然后我发送此消息(使用 TIdMessageTIdSMTP),但结果消息仅包含文本的第二部分。文本有超过 40,000 个字符。 当我在没有 html-tmplate(只有大文本)的情况下发送消息时,一切正常。

如何设置消息的长度?

我尝试设置 FIdMessage.ContentTransferEncoding := 'quoted-printable' and FIdSMTP.MsgLineLength := MAXWORD; 但它没有帮助我。

提前致谢。
下面是一些代码:

var
  FSMTP: TIdSMTP;
  FIdMessage: TIdMessage;
  idx: integer;
  i: Integer;
  FIdText: TIdText;
begin
  FSMTP := TIdSMTP.Create( nil );
  FIdMessage := TIdMessage.Create( nil );
  try
    try
      FIdMessage.ExtraHeaders.Clear;
      FIdMessage.MessageParts.Clear;

      // Attachments
      for idx := 0 to Attachments.Count - 1 do
        TIdAttachment.Create( FIdMessage.MessageParts,
          TEmailAttachment( Attachments.Items[ idx ] ).FLocalTemplateName );


      FIdMessage.From.Text := FFrom;
      FIdMessage.Recipients.EMailAddresses := FTo;
      FIdMessage.Subject := FSubject;
      if (FHtmlTemplateFilePath <> '') then
      begin
        FIdMessage.ContentType := 'multiparts/related; type="text/html"';
        AddAttachements(FIdMessage);  // procedure that added Attachments

        FIdText := TIdText.Create(FIdMessage.MessageParts, nil);
        FIdText.Body.Text := 'Please view a html version of this email';
        FIdText.ContentType := 'text/plain';


        FIdText := TIdText.Create(FIdMessage.MessageParts, nil);
        FIdText.Body.Text := FBody;
        FIdText.ContentType := 'text/html';

      end
      else
      begin
        FIdMessage.Body.Text := FBody;
      end;    

      FIdMessage.CCList.Clear;
      FIdMessage.ReceiptRecipient.Text := '';

      FSMTP.AuthenticationType := FSMTPAuthenticationType;
      FSMTP.UserID := FSMTPUserID;
      FSMTP.Password := FSMTPPassword;
      FSMTP.Host := FSMTPHost;
      FSMTP.Port := FSMTPPort;
      FSMTP.MsgLineLength := MAXWORD;

      RepeatRetryCount := FSMTPRepeatRetryCount;
      FSMTP.Connect;
       try
            FSMTP.Send( FIdMessage );
       finally
            FSMTP.Disconnect;
       end;
     except
       end;
  finally
    FSMTP.Free;
    FIdMessage.Free;
  end;
end;
procedure AddAttachements(AIdMessage: TidMessage);
var
  LCid: Integer;
  LFileName, LFileExt, LSearchFolder: String;
  LSearchResult: TSearchRec;
  Attachment: TIdAttachment;
begin
  FHtmlCids.Clear;
  LSearchFolder := ExtractFilePath(FHtmlTemplateFilePath)+ChangeFileExt(ExtractFileName(FHtmlTemplateFilePath),'');
  if (FindFirst(LSearchFolder + '_*', faDirectory, LSearchResult)=0) or
     (FindFirst(LSearchFolder + '.*', faDirectory, LSearchResult)=0)
  then
    LSearchFolder := LSearchResult.Name;

  FindClose(LSearchResult);
  if FindFirst(ExtractFilePath(FHtmlTemplateFilePath)+LSearchFolder+'\*.*', faAnyFile - faDirectory, LSearchResult)=0 then
  begin
    repeat
      Attachment := TIdAttachment.Create(AIdMessage.MessageParts, ExtractFilePath(FHtmlTemplateFilePath)+ LSearchFolder + '\' + LSearchResult.Name);
      LCid := Random(MaxInt);
      Attachment.ExtraHeaders.Values['Content-ID'] := IntToStr(LCid);
      LFileName := ExtractFileName(LSearchResult.Name);
      LFileExt := ExtractFileExt(LSearchResult.Name);
      if UpperCase(LFileExt) = '.XML' then
        Attachment.ContentType := 'text/xml'
      else if UpperCase(LFileExt) = '.PNG' then
        Attachment.ContentType := 'image/png'
      else if UpperCase(LFileExt) = '.THMX' then
        Attachment.ContentType := 'application/vnd.ms-officetheme'
      else if UpperCase(LFileExt) = '.JPG' then
        Attachment.ContentType := 'image/jpeg'
      else if UpperCase(LFileExt) = '.GIF' then
        Attachment.ContentType := 'image/gif'
      else if UpperCase(LFileExt) = '.SVG' then
        Attachment.ContentType := 'image/svg+xml'
      else if UpperCase(LFileExt) = '.TIF' then
        Attachment.ContentType := 'image/tiff'
      else if UpperCase(LFileExt) = '.TIFF' then
        Attachment.ContentType := 'image/tiff'
      else if UpperCase(LFileExt) = '.ICO' then
        Attachment.ContentType := 'image/vnd.microsoft.icon'
      else if UpperCase(LFileExt) = '.BMP' then
        Attachment.ContentType := 'image/bmp'
      else if UpperCase(LFileExt) = '.CSS' then
        Attachment.ContentType := 'text/css'
      else if UpperCase(LFileExt) = '.JS' then
        Attachment.ContentType := 'application/javascript'
      else if UpperCase(LFileExt) = '.JPEG' then
        Attachment.ContentType := 'image/jpeg'
      else if UpperCase(LFileExt) = '.WMZ' then
        Attachment.ContentType := 'application/x-ms-wmz'
      else raise Exception.CreateFmt('Unknown file type "%s"', [LFileExt]);
      FHtmlCids.AddObject(LSearchFolder+'/'+LFileName, TObject(LCid));
      FHtmlCids.AddObject(UrlEncode(LSearchFolder+'/'+LFileName), TObject(LCid));
    until FindNext(LSearchResult)<>0;
    FindClose(LSearchResult);
  end;
  FHtmlCids.Sort;
end;

TIdMessage 不限制文本长度。其他事情正在发生。我的猜测是您根本没有正确填写 TIdMessage。您没有显示 AddAttachments() 代码,但是您在 TIdText 对象之前添加了 TIdAttachment 对象,这是错误的,尤其是对于您正在使用的 ContentType。我建议您阅读 Indy 网站上的以下博客文章,了解 TIdMessage 中 HTML 电子邮件的正确结构:

HTML Messages

但是,请注意以下警告:

Unfortunately, Indy 9 does not handle the plaintext+html+images scenerio as well as it should. Indy 10 handles it better...

您显然没有使用 Indy 10(您将文件名传递给 TIdAttachment 构造函数这一事实就证明了这一点 - 该构造函数已移至新的 TIdAtttachmentFile class在 Indy 10 中)。

此外,仅供参考,您不需要设置 MsgLineLength 属性,因为它没有任何效果(事实上,我不知道 Indy 甚至还有那个 属性 - 它是 TIdMessageClient.WriteFoldedLine() 使用的死 属性,它本身是一个没有被任何东西使用的死方法。

感谢大家,我似乎找到了解决办法。 问题出在 CR LF 上。 在调用我的程序(见上文)发送消息之前,我在 html-template 中插入了大文本而不是 ##text##。首先,我替换了 my text<br> 上的所有 CR LF,然后替换了 my 上的 ##text##模板中的文本。 (我的文本 - 一些大文本)

结果我在发送前收到了邮件正文:

<html>
....
<body>
some large text <br> in one line. This text have more 40,000 characrets.....
</body>
</html>

按摩:

ine. This text have more 40,000 characrets

当我离开 CR LF 并添加标签 <br> 时,我得到了这个正文:

<html>
....
  <body>
    some large text <br> 
    in one line. This text have more 40,000 characrets.....
  </body>
</html>

和消息:

some large text
in one line. This text have more 40,000 characrets.....

所以,在这种情况下,如果所有文本都在一行中 -> 信息不完整,如果 html 中的文本在几行中 -> 一切正常

PS。对不起我的英语