PHP 邮件格式问题 - 为啥 CRLF 标题行结尾会破坏 Outlook 中的 HTML 电子邮件?
Posted
技术标签:
【中文标题】PHP 邮件格式问题 - 为啥 CRLF 标题行结尾会破坏 Outlook 中的 HTML 电子邮件?【英文标题】:PHP mail formatting issue - Why do CRLF header line endings break HTML email in Outlook?PHP 邮件格式问题 - 为什么 CRLF 标题行结尾会破坏 Outlook 中的 HTML 电子邮件? 【发布时间】:2011-03-27 20:08:26 【问题描述】:我正在使用 php 原生 mail()
函数发送 html 电子邮件,但在用户最常见的电子邮件客户端 - Outlook 2007 中存在格式问题(除了一些其他电子邮件clients) - 所有的 html 标签都被暴露出来,所以对于非 web 开发者来说,这看起来像是胡言乱语。
我发送 HTML 电子邮件的方式与 PHP manual 演示它的方式相同。示例:
$message = get_HTML_email_with_valid_formatting();
$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=UTF-8\r\n";
$headers .= "From: example.com <info@example.com>\r\n";
$headers .= "Reply-To: donotreply@example.com\r\n";
mail('me@example.com', 'test', $message, $headers);
因为测试各种电子邮件客户端很困难,所以我注册了http://litmusapp.com/,因此我可以看到 47 个不同电子邮件客户端中的电子邮件截图。大多数都可以(例如 gmail、thunderbird、Lotus Notes),但所有不同版本的 Outlook 都不好。
为了解决格式问题,我做了以下操作:
-
删除
$headers = "MIME-Version: 1.0\r\n";
邮件标头。
确保我只以“\n
”而不是“\r\n
”结束我的标题。
有谁知道为什么我在不符合手册的情况下使用 HTML 电子邮件会获得更好的结果?
信息:
我在 RHEL 5.5 上使用 postfix 版本 2.3.3。 PHP 版本 5.3.2【问题讨论】:
“我正在使用 PHP 本机 mail() 函数来发送 HTML 电子邮件” - 嗯,这是你的问题* ;-) 你有没有考虑过使用类似的东西,例如swiftmailer.org ? | * 也许不是mail()函数本身,而是mail()、一些字符串连接&试图同时解决协议和应用程序级问题的组合。 【参考方案1】:如果你使用postfixsendmail_path = "tr -d '\r'|sendmail -t -i"放到php.ini中。
【讨论】:
【参考方案2】:您有 2 个解决方案:
-
将具有“sendmail_fix_line_endings”的 Postfix 升级到 +2.9(终于!!!)参见:Postfix documentation
安装 Sendmail(工作正常!)
我有一个带有 LAMP 堆栈的 VMware 映像。为了发送电子邮件,我最终决定:
安装 Sendmail 使用我的 ISP 的 smtp(因为它只是一个开发盒)。对于 sendmail 部分,您可以按照以下方式操作:http://www.geoffke.be/nieuws/13/
重要提示:一些网络托管商可能只使用稳定的软件包,这意味着您可以拥有... 2.9 之前的 Postfix!示例:http://packages.debian.org/search?keywords=postfix
【讨论】:
【参考方案3】:我怀疑这是我的 Postfix 版本 - 版本 2.3.3 已有 5 年历史,也许它正在将 LF 转换为 CRLF,但看到我已经有 CRLF,我想我正在发送 CRCRLF邮件客户端。
很遗憾,我无法升级 Postfix。因此,目前我已将代码转换为使用可配置变量作为行尾,以便将来轻松更改:
$eol = "\n";
$message = get_HTML_email_with_valid_formatting();
$headers = "MIME-Version: 1.0".$eol;
$headers .= "Content-Type: text/html; charset=UTF-8".$eol;
$headers .= "From: example.com <info@example.com>".$eol;
$headers .= "Reply-To: donotreply@example.com".$eol;
mail('me@example.com', 'test', $message, $headers);
【讨论】:
【参考方案4】:电子邮件被解释为 text/plain 而不是预期的 html。原因是 text/html 是多部分子类型,因此需要边界声明。
您的代码缺少 标题边界 声明:
$message = get_HTML_email_with_valid_formatting();
$headers = "MIME-Version: 1.0\r\n";
$headers .= "--$boundary\r\n"."Content-Type: text/html; charset=ISO-8859-1\r\n";
$headers .= "From: example.com <info@example.com>\r\n";
$headers .= "Reply-To: donotreply@example.com\r\n";
mail('me@example.com', 'test', $message, $headers);
查看有关 MIME 和多部分消息的 wiki: http://en.wikipedia.org/wiki/MIME#Multipart_messages
【讨论】:
...这样结果至少是一致的,所有电子邮件客户端都会显示垃圾邮件? 感谢您的评论。我的印象是 HTML 电子邮件并不严格需要是多部分的。即拥有文本版本是一种很好的做法,但不是必需的。以上是关于PHP 邮件格式问题 - 为啥 CRLF 标题行结尾会破坏 Outlook 中的 HTML 电子邮件?的主要内容,如果未能解决你的问题,请参考以下文章
为啥这个 PHP 电子邮件脚本不会发送到我的 Yahoo 电子邮件?