【问题标题】:sending mail from php: headers are interpreted as body?从 php 发送邮件:标题被解释为正文?
【发布时间】:2010-12-11 07:52:42
【问题描述】:

当我从 php 发送邮件时,在标题中使用 \r\n 作为换行符 (as it should be according to documentation)

$headers = "From: $email\r\n"; 
$headers .= "Reply-To:  Just me <$email>\r\n"; 
$headers .= 'Content-type: text/plain; charset=iso-8859-1' . "\r\n";
$headers .= "Content-Transfer-Encoding: 8bit\r\n";
$subject = "Hello world";
$body = "<html><p>Hey, whats up?</p></html>";

mail($to, $subject, $body, $headers);

某些邮件客户端会将 \r\n 解释为两个换行符。所以对于上面的这个mail(),真正的邮件内容应该是这样的:

X-Message-Delivery: Vj0LEdMMtPAYT0xO0Q9MTtTQ0w9MA==
X-Message-Status: n
Received: from server75.publicompserver.de ([92.43.108.63]) by snt0-mc2-f13.Snt0.hotmail.com with Microsoft SMTPSVC(6.0.3790.4675);
 Thu, 9 Dec 2010 12:09:22 -0800
Message-ID: <40177C.70807@justme.org>
[lots of other headers]
Date: Thu, 09 Dec 2010 21:09:32 +0100
X-OriginalArrivalTime: 09 Dec 2010 20:09:22.0873 (UTC) FILETIME=[F88C3A90:01CB97DC]
From: $email

Reply-To:  Just me <$email>

Content-type: text/html; charset=iso-8859-1

Content-Transfer-Encoding: 8bit

<html><p>Hey, whats up?</p></html>

现在一些客户端(例如 googlemail)将忽略这些额外的换行符。其他人(雷鸟)会将第一个额外的换行符解释为标题的结尾,并将其余的标题行解释为正文的一部分(丢失标题信息,在这种情况下将邮件呈现为文本而不是 html)。

我在其他邮件发送网站上也看到了同样的问题。

这里发生了什么? \r\n 是根据文档的正确换行符,还是这里有其他问题? 以及如何解决?将换行符更改为 \n 而不是 \r\n 似乎有帮助,但由于文档说“你应该使用 \r\n”,这不可能是正确的,可以吗?

【问题讨论】:

  • 在您之前的问题中,我提到了PHP_EOL 常量。你试过这个吗?
  • 由于这些脚本在 Apache/Unix 上运行,PHP_EOL 应该是\n,不是吗?
  • 也许有人可以解释一下 unix sendmail 脚本如何将\n 转换为\r\n
  • 您在示例中与\r\n 的用法不一致。您的某些标头以 CRLF 结尾,有些仅以 LF 结尾。
  • @Thanatos,是的,对不起,我从不同的来源整理了这个例子,因为我不希望它包含真实的电子邮件地址。现已更正。

标签: php email


【解决方案1】:

http://php.net/manual/en/function.mail.php 的文档中提到了这一点:“如果未收到消息,请尝试仅使用 LF (\n)。一些质量差的 Unix 邮件传输代理会自动将 LF 替换为 CRLF(如果CRLF)。这应该是最后的手段,因为它不符合 » RFC 2822。"

所以,正如你所说:这是不对的,但这是现实。

【讨论】:

  • 所以我应该使用 \r\n 直到其中一位邮件接收者抱怨,而不是改用 \n ?但是我怎么能确定他们会抱怨(尤其是在回复标头丢失的情况下)所以我会注意到而不是删除消息?
  • 我的猜测是,为了获得最大的兼容性,请仅使用 \n,该死的 RFC,只要您的测试表明该方法没有问题。
【解决方案2】:

正如您在上一个问题中提到的那样。每个平台以不同的方式(CRLF 或 LF)划分线。最好通过 PHP_EOL 常量将这个决定留给 PHP,PHP 会处理它。

【讨论】:

【解决方案3】:

在您的代码中,您将 \r\n 用于某些标题行,而仅 \n 用于其他标题行。如果您保持一致,也许不会发生此问题。

【讨论】:

  • 哦,抱歉,这不是真正的代码,这只是我在运行中制作的一些示例 - 代码本身是一致的,我的错误!
猜你喜欢
  • 1970-01-01
  • 2011-12-04
  • 1970-01-01
  • 2012-08-17
  • 1970-01-01
  • 2017-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多