如何使用Ruby处理UTF-8电子邮件标题(如Subject :)?

我是一封电子邮件n00b,但我正在开发一个发送带有Unicode字符的HTML电子邮件的应用程序(正如我的朋友所说“享受编码地狱”)。

Subject:标题来自用户输入,因此可能包含Unicode字符。 一些邮件客户端(如GMail和Outlook 2007)可以正常使用,但从我的阅读中看来,正确的方法是对标头使用MIME编码字编码 。

我找不到一个Ruby库来做这件事。 有吗?

此外,是否有一个标题要添加,告诉邮件客户端在显示邮件时使用UTF-8? 我们发送多部分电子邮件,因此我们的Content-Typemultipart/mixed 。 Apple Mail.app特别没有使用正确的编码,即使它在各个部分中指定为UTF-8。

您可以选择使用Base64编码执行相同操作:

 require "base64" value = Base64.encode64("Your UTF-8 string") header = "=?UTF-8?B?" + value + "?=" 

注意标记Base64编码有效载荷的“B”,而不是标记“Q编码”有效载荷的“Q”。 后者可以通过对字符串进行URL编码并用“=”替换所有“%”字符来伪造。

通过“伪造”我的意思是:它会产生一个有效的结果,但可能编码的字符比必要的多。 规范允许使用"=" + ByteCodeAsHex对每个字符进行编码,它只会损害原始标头的人类可读性。 当没有别的东西可用时.gsub(/%/, "=") UrlEncode是+ .gsub(/%/, "=")并不是一个糟糕的妥协。

啊啊! ActionMailer::Quoting quoted_printable有一个quoted_printable方法。

所以这就是我做的:

 def my_email(foo) ... @subject = quoted_printable(foo.some_subject_with_accented_chars, 'utf-8') ... end 

这样做确信Mail.app使用UTF-8显示其余的电子邮件。 现在来测试剩下的!

由于没有一个答案讲述了纯Ruby的整个消息,所以它就是这样。

 Net::SMTP.start("localhost") do |smtp| smtp.open_message_stream opts[:sender_address], opts[:receiver_address] do |f| f.puts "Content-type: text/plain; charset=UTF-8" f.puts from f.puts to f.puts subject f.puts message end end 

在这里打开与localhost的连接。 也可以使用外部SMTP服务器,请参阅net / smtp文档。

第一行设置消息中使用的字符集。 其余的行是分别定义的变量:

from是From: Name here 的地址From: Name here 。 如果不需要名称,则只能指定地址,例如From: address@here.fi

使用相同的语法,例外From:更改为To: .

主题是主语:主题在这里。 对于UTF-8,它需要进行Base64编码才能正确显示给客户端。

 subject = "Subject: =?UTF-8?B?" + Base64.strict_encode64(subject) + "?=" 

消息是以UTF-8编码的纯文本消息,没有任何前缀。 net / smtp将负责形成正确的邮件。