delphi - 带有 Unicode 主题的 Indy 消息

标签 delphi unicode indy

我需要创建一个带有 Unicode 主题的 IdMessage(例如“本语 - 测试”)

我试过设置它使用

Msg.Subject := UTF8Encode(subject);

其中 subject 是包含上述文本的 WideString
但是当我查看编码的主题(通过将消息保存到文件)时,它看起来像这样:
Subject: =?UTF-8?Q?=C3=A6=C5=93=C2=AC=C3=A8=C2=AA=C5=BE?= - test

代替
Subject: =?UTF-8?Q?=E6=0C=AC=E8=AA=9E?= - test

Outlook 将其显示为“本語 - 测试”

关于我哪里出错的任何指示?

Delphi 2006 (pre-unicode), Indy 10 (相当新的来源)

最佳答案

在 Unicode 之前的 Delphi 版本中,所有内容都基于 AnsiString ,您分配给 TIdMessage.Subject 的值属性(以及 AnsiString 的任何其他 TIdMessage 属性,就此而言)必须使用操作系统默认字符编码进行编码。您正在将其编码为 UTF-8,这是行不通的。这是因为 TIdMessage将首先解码 Subject使用操作系统默认编码将值转换为 Unicode,然后使用 TIdMessage.OnInitializeISO 提供的编码参数对 Unicode 数据进行 MIME 编码。事件,如果没有分配事件处理程序,则为默认值(在这种情况下,这些参数是 CharSet=UTF-8HeaderEncoding=QuotedPrintable )。 TIdMessage没有机制允许您指定用于任何 AnsiString 的编码。您分配给它的数据。所以唯一的可能发送值'本語 - test'Subject属性是分配您的来源WideString原样到属性,让 RTL 将数据转换为 AnsiString使用操作系统默认编码:

Msg.Subject := subject;

但是,如果操作系统不支持正在使用的 Unicode 字符,则会丢失数据。在这种情况下无法避免。

另一种方法是设置 Subject属性为空字符串,然后使用 TIdMessage.ExtraHeaders属性,以便您可以提供自己的标题值,该值将按原样放入电子邮件中。使用这种方法,您可以调用 Indy 的 EncodeHeader()直接发挥作用。在 Unicode 之前的 Delphi 版本中,它有一个可选的 ASrcEncoding默认为操作系统默认编码的参数(TIdMessage 当前在编码 header 时不提供该参数的值):
uses
  ..., IdCoderHeader;

Msg.Subject := '';
Msg.ExtraHeaders.Values['Subject'] := EncodeHeader(UTF8Encode(subject), '', 'Q', 'UTF-8', IndyTextEncoding_UTF8);

这样,EncodeHeader()将能够避免冗余转换,因为它可以检测到源和目标字符编码都是 UTF-8,因此只需按原样对源 UTF-8 数据进行 MIME 编码。更糟糕的是,即使它没有检测到字符编码相同,它也会简单地将源数据使用 UTF-8 解码为 Unicode,然后将其重新编码回 UTF-8。这些是无损转换,因此不会丢失任何数据。

仅供引用,您显示的 Unicode 字符的正确编码是:
Subject: =?UTF-8?Q?=E6=9C=AC=E8=AA=9E?= - test

不是
Subject: =?UTF-8?Q?=E6=0C=AC=E8=AA=9E?= - test

正如你所展示的。注意第二个编码的八位字节是9C而不是 0C .

关于delphi - 带有 Unicode 主题的 Indy 消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24651339/

相关文章:

php - 为什么我无法在 Codeigniter 中读取带有中文字符的输入值?

python - 安装 Mayavi : UnicodeEncodeError: 'charmap' codec can't encode character

delphi - 当我在表单上放置 TidSMTP 时出现访问冲突

C++ Builder - 使用 TIdTCPServer 以编程方式创建 TCP 服务器连接

Delphi Firedac 内存表

delphi - Delphi 6 是否有一个实用程序可以分析类层次结构并可以查询方法祖先?

android - 通过 HTTPS/TLS 将 Delphi 移动应用程序连接到 Web 服务器

performance - 计算例程的速度?

sorting - 使用 LDML 文件中指定的整理顺序进行行排序

delphi - Delphi 2009中Indy 10的逐步升级