使用 Indy 组件的最大消息长度
Maximum length of message using Indy components
我正在尝试从 delphi 发送消息 - 代码使用 TIdMessage
。该消息由两部分组成:text/plain
和 text/html
。
我有 html-page 作为模板和一些需要插入模板的大文本(在标记为 ##text## 的特殊位置)。合并模板和文本后,我得到了新消息的正文。然后我发送此消息(使用 TIdMessage
和 TIdSMTP
),但结果消息仅包含文本的第二部分。文本有超过 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 电子邮件的正确结构:
但是,请注意以下警告:
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。对不起我的英语
我正在尝试从 delphi 发送消息 - 代码使用 TIdMessage
。该消息由两部分组成:text/plain
和 text/html
。
我有 html-page 作为模板和一些需要插入模板的大文本(在标记为 ##text## 的特殊位置)。合并模板和文本后,我得到了新消息的正文。然后我发送此消息(使用 TIdMessage
和 TIdSMTP
),但结果消息仅包含文本的第二部分。文本有超过 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 电子邮件的正确结构:
但是,请注意以下警告:
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。对不起我的英语