Indy 使用具有 UTF-8 字符的收件人发送电子邮件
Indy send email with receivers having UTF-8 characters
我正在尝试在 Indy 10 中发送带有 TIdSMTP
组件的电子邮件,我的收件人列表中包含 Unicode 字符(如 Роман Безяк <roman_bezjak@yahoo.com>
)。但是在发送邮件时,在电子邮件的 To
header 中我看到了:"?????????" <roman_bezjak@yahoo.com>
。谁能帮我解决这个编码问题?
我的程序是这样的:
procedure TMailClientForm.btnSendEmailClick(Sender: TObject);
var
mes : TIdMessage;
i : Integer;
begin
with SMTPClient do begin
Host := serverHost;
Port := SmtpServerPort;
Username := myUserName;
Password := myPassword;
UseTLS := utUseImplicitTLS;
end;
try
mes := tidmessage.Create(nil);
try
with mes do begin
ContentType := 'text/plain';
ClearBody;
Body.Text := memoEmailBody.Text;
Subject := txtEmailSubject.text;
From.Address := SMTPClient.Username;
From.Name := myName; // cyrillic symbols!
Recipients.Add.Address := myReceiver; // cyrillic symbols! like 'Роман Безяк <roman_bezjak@yahoo.com>'
CharSet := 'utf-8';
end;
if fileNames.Count > 0 then // attachments - the files are in the stringlist fileNames
mes.ContentType := 'multipart/mixed';
for i := 0 to fileNames.count - 1 do begin
if FileExists(fileNames[i]) then
TIdAttachmentFile.Create(mes.MessageParts, fileNames[i]);
end;
try
try
try
SMTPClient.Connect;
except
on e : Exception do begin
MessageDlg('ERROR=' + SMTPClient.LastCmdResult.Text.Text, mtError, [mbOK], 0);
Exit;
end;
end;
try
SMTPClient.Send(mes);
except
on e : Exception do begin
MessageDlg('ERROR=' + SMTPClient.LastCmdResult.Text.Text, mtError, [mbOK], 0);
Exit;
end;
end;
finally
if SMTPClient.Connected then
SMTPClient.Disconnect;
end;
fileNames.clear;
except
on e:exception do begin
MessageDlg(e.message, mtError, [mbOK], 0);
end;
end;
finally
mes.Free;
end;
except
on e:exception do begin
MessageDlg(e.message, mtError, [mbOK], 0);
end;
end;
end;
Recipients.Add.Address := myReceiver; // cyrillic symbols! like 'Роман Безяк <roman_bezjak@yahoo.com>'
如果 myReceiver
包含姓名和电子邮件地址,您需要使用 TIdEMailAddressItem.Text
属性 而不是 TIdEMailAddressItem.Address
属性:
Recipients.Add.Text := myReceiver; // cyrillic symbols! like 'Роман Безяк <roman_bezjak@yahoo.com>'
// Name becomes 'Роман Безяк'
// Address becomes 'roman_bezjak@yahoo.com'...
TIdEmailAddressItem.Text
属性 setter 方法解析输入字符串并相应地将其拆分为 TIdEmailAddressItem.Name
和 TIdEmailAddressItem.Address
属性。
TIdEmailAddressItem.Address
属性 根本没有 setter 方法,所以无论你分配什么,都会使用 as-is.
编码电子邮件时,如果存在任何 non-ASCII 个字符,TIdEmailAddressItem.Name
值会根据 RFC 2047 得到 MIME-encoded。 TIdEmailAddressItem.Address
值不会得到 MIME-encoded,因为假设电子邮件地址只包含 ASCII 字符(Unicode 电子邮件地址确实存在,但还不常用)。电子邮件 headers 必须是 ASCII,所以你看到 Роман Безяк
变成了 ?????????
因为你把它放在了 TIdEmailAddressItem.Address
属性 并且它被转换了 as-is 到 ASCII(其中 non-ASCII 个字符变为 ?
)而不是 MIME-encoded.
因此,通过将 Name
与 Address
分开,您应该会看到 Роман Безяк
得到了正确处理。
我正在尝试在 Indy 10 中发送带有 TIdSMTP
组件的电子邮件,我的收件人列表中包含 Unicode 字符(如 Роман Безяк <roman_bezjak@yahoo.com>
)。但是在发送邮件时,在电子邮件的 To
header 中我看到了:"?????????" <roman_bezjak@yahoo.com>
。谁能帮我解决这个编码问题?
我的程序是这样的:
procedure TMailClientForm.btnSendEmailClick(Sender: TObject);
var
mes : TIdMessage;
i : Integer;
begin
with SMTPClient do begin
Host := serverHost;
Port := SmtpServerPort;
Username := myUserName;
Password := myPassword;
UseTLS := utUseImplicitTLS;
end;
try
mes := tidmessage.Create(nil);
try
with mes do begin
ContentType := 'text/plain';
ClearBody;
Body.Text := memoEmailBody.Text;
Subject := txtEmailSubject.text;
From.Address := SMTPClient.Username;
From.Name := myName; // cyrillic symbols!
Recipients.Add.Address := myReceiver; // cyrillic symbols! like 'Роман Безяк <roman_bezjak@yahoo.com>'
CharSet := 'utf-8';
end;
if fileNames.Count > 0 then // attachments - the files are in the stringlist fileNames
mes.ContentType := 'multipart/mixed';
for i := 0 to fileNames.count - 1 do begin
if FileExists(fileNames[i]) then
TIdAttachmentFile.Create(mes.MessageParts, fileNames[i]);
end;
try
try
try
SMTPClient.Connect;
except
on e : Exception do begin
MessageDlg('ERROR=' + SMTPClient.LastCmdResult.Text.Text, mtError, [mbOK], 0);
Exit;
end;
end;
try
SMTPClient.Send(mes);
except
on e : Exception do begin
MessageDlg('ERROR=' + SMTPClient.LastCmdResult.Text.Text, mtError, [mbOK], 0);
Exit;
end;
end;
finally
if SMTPClient.Connected then
SMTPClient.Disconnect;
end;
fileNames.clear;
except
on e:exception do begin
MessageDlg(e.message, mtError, [mbOK], 0);
end;
end;
finally
mes.Free;
end;
except
on e:exception do begin
MessageDlg(e.message, mtError, [mbOK], 0);
end;
end;
end;
Recipients.Add.Address := myReceiver; // cyrillic symbols! like 'Роман Безяк <roman_bezjak@yahoo.com>'
如果 myReceiver
包含姓名和电子邮件地址,您需要使用 TIdEMailAddressItem.Text
属性 而不是 TIdEMailAddressItem.Address
属性:
Recipients.Add.Text := myReceiver; // cyrillic symbols! like 'Роман Безяк <roman_bezjak@yahoo.com>'
// Name becomes 'Роман Безяк'
// Address becomes 'roman_bezjak@yahoo.com'...
TIdEmailAddressItem.Text
属性 setter 方法解析输入字符串并相应地将其拆分为 TIdEmailAddressItem.Name
和 TIdEmailAddressItem.Address
属性。
TIdEmailAddressItem.Address
属性 根本没有 setter 方法,所以无论你分配什么,都会使用 as-is.
编码电子邮件时,如果存在任何 non-ASCII 个字符,TIdEmailAddressItem.Name
值会根据 RFC 2047 得到 MIME-encoded。 TIdEmailAddressItem.Address
值不会得到 MIME-encoded,因为假设电子邮件地址只包含 ASCII 字符(Unicode 电子邮件地址确实存在,但还不常用)。电子邮件 headers 必须是 ASCII,所以你看到 Роман Безяк
变成了 ?????????
因为你把它放在了 TIdEmailAddressItem.Address
属性 并且它被转换了 as-is 到 ASCII(其中 non-ASCII 个字符变为 ?
)而不是 MIME-encoded.
因此,通过将 Name
与 Address
分开,您应该会看到 Роман Безяк
得到了正确处理。