【问题标题】: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 都不好。

为了解决格式问题,我做了以下操作:

  1. 删除$headers = "MIME-Version: 1.0\r\n"; 邮件标头。
  2. 确保我只以“\n”而不是“\r\n”结束我的标题。

有谁知道为什么我在不符合手册的情况下使用 HTML 电子邮件会获得更好的结果?

信息:

  • 我在 RHEL 5.5 上使用 postfix 版本 2.3.3。
  • PHP 版本 5.3.2

【问题讨论】:

  • “我正在使用 PHP 本机 mail() 函数来发送 HTML 电子邮件” - 嗯,这是你的问题* ;-) 你有没有考虑过使用类似的东西,例如swiftmailer.org ? | * 也许不是mail()函数本身,而是mail()、一些字符串连接&试图同时解决协议和应用程序级问题的组合。

标签: php mime postfix-mta html-email email-formats


【解决方案1】:

如果你使用postfixsendmail_path = "tr -d '\r'|sendmail -t -i"放到php.ini中。

【讨论】:

    【解决方案2】:

    您有 2 个解决方案:

    1. 将具有“sendmail_fix_line_endings”的 Postfix 升级到 +2.9(终于!!!)参见:Postfix documentation
    2. 安装 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 电子邮件并不严格需要是多部分的。即拥有文本版本是一种很好的做法,但不是必需的。
        猜你喜欢
        • 2014-12-17
        • 1970-01-01
        • 2017-07-21
        • 1970-01-01
        • 2023-03-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多