如何在电子邮件的主题行中获得 HTML 的效果?
How can I get effect of HTML into email's subject line?
我正在使用 Apache Commons Email API 从我的应用程序发送电子邮件。我无法获得已发送电子邮件的正确主题行。例如,有问题的主题行:“This is my email Subject line companyName<sup>®</sup>
”。我希望主题行是“I want something likewise - companyName®
”,但没有显示上标效果。
主题行的呈现由电子邮件客户端执行;即电子邮件收件人用来阅读他/她的邮件的工具。这些工具实现了一个称为 RFC 822 的标准,该标准指定了电子邮件的表示方式;例如电子邮件 header 是什么,它们是什么意思,以及电子邮件的 body(内容)是如何表示的。
问题来了。 RFC 822 于 1982 年指定。那比 Unicode 早很多年。 RFC 822 已经更新了几次,最新版本是 RFC 5322。但是,RFC 5322 仍然保留电子邮件 header 字段(例如“主题:”字段)必须由 ASCII 字符组成的约束。 (换句话说,直接在主题中使用 UTF-8 将违反规范。)
幸运的是有一个解决方法。 RFC 1342 标准提供了一种语法,用于通过 ASCII 传递以另一种字符编码(例如 UTF-8)编码的文本。 MIME规范已经明确表示
您可以在电子邮件 headers.
中进行 RFC 1342 编码
RFC 1342编码的一般形式为:
=?charset?encoding?encoded-text?=
其中 charset
是标准字符集名称,encoding
是 Q
或 B
(引号字符串或 base64),encoded-text
是指定字符集中表示的文本,并使用指定编码进行编码。例如:
=?utf-8?Q?hello?=
详情请参考RFC。
请注意,如果您使用 javax.mail
API 构造电子邮件,则设置 UTF-8 编码电子邮件主题的正确方法如下:
message.setSubject("We love Java® !!", "UTF-8");
或使用 Java 的 \uxxxx
Unicode 转义。
不幸的是,Apache Commons Email API 不允许您这样做。但是(如果我正确阅读了代码),它将尝试使用电子邮件的字符集(请参阅 setCharset()
)或默认字符集对包含 non-ASCII 个字符的 header 字段进行编码。
因此,如果在使用 Apache Commons Email API 时没有正确传递普通的“®
”,解决方案是使用 setCharset("UTF-8")
设置电子邮件的字符集. (事实上 ,字符已经被正确处理,所以这可能是多余的。)
这解决了 Unicode 字符的问题。您还试图在“主题:”中包含 HTML 标记。据我所知,任何电子邮件规范都不支持邮件 headers 中的 HTML 标记。事实上,如果电子邮件发送者 确实 试图在主题中呈现 HTML 标记,则可以说是违反规范:header.
虽然有一个替代方案,因为 Unicode 允许您修改字符以使其成为下标或上标;有关详细信息,请参阅 this Wikipedia page。如果您尝试这种方法,您将受制于收件人的电子邮件客户端的 Unicode 呈现。
@stephen-c 回答正确,作为补充,我会分享我的部分代码。
import org.apache.commons.codec.binary.Base64;
import java.nio.charset.StandardCharsets;
import javax.mail.Message;
import javax.mail.Session;
....
Message message = new MimeMessage(session);
String subject;
...
byte[] bytesEncoded = Base64.encodeBase64(subject.getBytes(StandardCharsets.UTF_8));
message.setSubject("=?UTF-8?B?" + new String(bytesEncoded) + "?=");
我正在使用 Apache Commons Email API 从我的应用程序发送电子邮件。我无法获得已发送电子邮件的正确主题行。例如,有问题的主题行:“This is my email Subject line companyName<sup>®</sup>
”。我希望主题行是“I want something likewise - companyName®
”,但没有显示上标效果。
主题行的呈现由电子邮件客户端执行;即电子邮件收件人用来阅读他/她的邮件的工具。这些工具实现了一个称为 RFC 822 的标准,该标准指定了电子邮件的表示方式;例如电子邮件 header 是什么,它们是什么意思,以及电子邮件的 body(内容)是如何表示的。
问题来了。 RFC 822 于 1982 年指定。那比 Unicode 早很多年。 RFC 822 已经更新了几次,最新版本是 RFC 5322。但是,RFC 5322 仍然保留电子邮件 header 字段(例如“主题:”字段)必须由 ASCII 字符组成的约束。 (换句话说,直接在主题中使用 UTF-8 将违反规范。)
幸运的是有一个解决方法。 RFC 1342 标准提供了一种语法,用于通过 ASCII 传递以另一种字符编码(例如 UTF-8)编码的文本。 MIME规范已经明确表示 您可以在电子邮件 headers.
中进行 RFC 1342 编码RFC 1342编码的一般形式为:
=?charset?encoding?encoded-text?=
其中 charset
是标准字符集名称,encoding
是 Q
或 B
(引号字符串或 base64),encoded-text
是指定字符集中表示的文本,并使用指定编码进行编码。例如:
=?utf-8?Q?hello?=
详情请参考RFC。
请注意,如果您使用 javax.mail
API 构造电子邮件,则设置 UTF-8 编码电子邮件主题的正确方法如下:
message.setSubject("We love Java® !!", "UTF-8");
或使用 Java 的 \uxxxx
Unicode 转义。
不幸的是,Apache Commons Email API 不允许您这样做。但是(如果我正确阅读了代码),它将尝试使用电子邮件的字符集(请参阅 setCharset()
)或默认字符集对包含 non-ASCII 个字符的 header 字段进行编码。
因此,如果在使用 Apache Commons Email API 时没有正确传递普通的“®
”,解决方案是使用 setCharset("UTF-8")
设置电子邮件的字符集. (事实上 ,字符已经被正确处理,所以这可能是多余的。)
这解决了 Unicode 字符的问题。您还试图在“主题:”中包含 HTML 标记。据我所知,任何电子邮件规范都不支持邮件 headers 中的 HTML 标记。事实上,如果电子邮件发送者 确实 试图在主题中呈现 HTML 标记,则可以说是违反规范:header.
虽然有一个替代方案,因为 Unicode 允许您修改字符以使其成为下标或上标;有关详细信息,请参阅 this Wikipedia page。如果您尝试这种方法,您将受制于收件人的电子邮件客户端的 Unicode 呈现。
@stephen-c 回答正确,作为补充,我会分享我的部分代码。
import org.apache.commons.codec.binary.Base64;
import java.nio.charset.StandardCharsets;
import javax.mail.Message;
import javax.mail.Session;
....
Message message = new MimeMessage(session);
String subject;
...
byte[] bytesEncoded = Base64.encodeBase64(subject.getBytes(StandardCharsets.UTF_8));
message.setSubject("=?UTF-8?B?" + new String(bytesEncoded) + "?=");