【问题标题】:Random HTML characters being encoded in emails在电子邮件中编码的随机 HTML 字符
【发布时间】:2015-07-09 08:31:40
【问题描述】:

我正在使用 PHP 生成一封输出 HTML 表格的电子邮件。表格的大部分内容都很好,但一些<> 字符被随机编码为<>。它并不总是在同一个地方进行。有时它只发生在一个地方,有时根本不发生,有时在多个地方发生。

这是我的电子邮件客户端看到的表格中间的代码 sn-p。注意不应该存在的插入的< /tr>

<tr>  
  <td>SERVER_SOFTWARE</td>
  <td>Apache/2.2.29 (Red Hat)</td>
</tr>
<tr>
  <td>SERVER_PROTOCOL</td>
  <td>HTTP/1.1</td>
  &lt; /tr&gt;
</tr>
<tr>
  <td>REQUEST_METHOD</td>
  <td>POST</td>
</tr>

电子邮件明文部分中的同一段:(再次注意,&lt;/tr&gt; 以某种方式被插入。)

SERVER_SOFTWARE Apache/2.2.29 (Red Hat)
SERVER_PROTOCOL HTTP/1.1 < /tr>
REQUEST_METHOD POST

我在发送前在标头中将其设置为 UTF-8:

$headers  = "MIME-Version: 1.0\r\nContent-Type: text/html; charset=UTF-8\r\nContent-Transfer-Encoding: quoted-printable";

(附注:我之前使用charset=ISO-8859-1时遇到了完全相同的问题。)

但尽管如此,它还是以某种方式显示在US-ASCII

Content-type: text/html;
    charset="US-ASCII"
Content-transfer-encoding: quoted-printable

生成电子邮件的 PHP 脚本如下所示:

//generate $table
$indicesServer = array('PHP_SELF', 'argv', 'argc', 'GATEWAY_INTERFACE', 'SERVER_ADDR', 'SERVER_NAME', 'SERVER_SOFTWARE', 'SERVER_PROTOCOL', 'REQUEST_METHOD', 'REQUEST_TIME', 'REQUEST_TIME_FLOAT', 'QUERY_STRING', 'DOCUMENT_ROOT', 'HTTP_ACCEPT', 'HTTP_ACCEPT_CHARSET', 'HTTP_ACCEPT_ENCODING', 'HTTP_ACCEPT_LANGUAGE', 'HTTP_CONNECTION', 'HTTP_HOST', 'HTTP_REFERER', 'HTTP_USER_AGENT', 'HTTPS', 'REMOTE_ADDR', 'REMOTE_HOST', 'REMOTE_PORT', 'REMOTE_USER', 'REDIRECT_REMOTE_USER', 'SCRIPT_FILENAME', 'SERVER_ADMIN', 'SERVER_PORT', 'SERVER_SIGNATURE', 'PATH_TRANSLATED', 'SCRIPT_NAME', 'REQUEST_URI', 'PHP_AUTH_DIGEST', 'PHP_AUTH_USER', 'PHP_AUTH_PW', 'AUTH_TYPE', 'PATH_INFO', 'ORIG_PATH_INFO') ;
$table = '<table cellpadding="3" cellspacing="0" border="1" bordercolor="#bbb">';
foreach ($indicesServer as $arg) {
    if (isset($_SERVER[$arg])) {
        $table .= '<tr><td>'.$arg.'</td><td>' . $_SERVER[$arg] . '</td></tr>' ;
    } else {
        $table .= '<tr><td>'.$arg.'</td><td>-</td></tr>' ;
    }
}
$table .=  '</table>' ;

//set up email
$to = [redacted];
$subject = [redacted];
$email_body = "Heres data:" . $table;
$headers  = "MIME-Version: 1.0\r\nContent-Type: text/html; charset=UTF-8\r\nContent-Transfer-Encoding: quoted-printable";

//send email
mail($to, $subject, $email_body, $headers);

编辑: 我注意到 HTML 属性变得混乱了。它与等号的quoted-printable 编码有关。 = 按预期编码为 =3D,但有时下一个字符会被删除!因此发生了以下情况:

&lt;a href="http://example.com"&gt; 变成 &lt;a href=3D"ttp://example.com"&gt;

&lt;table cellpadding=3 cellspacing=0 border=1&gt; 变成 &lt;table cellpadding&lt;ellspacingorder=3D"&amp;lt;tr"&gt;

【问题讨论】:

  • 你试过charset=ISO-8859-1吗?
  • @PedroLobito,是的。已经在原始问题中提到了这一点。
  • 你说得对,请原谅。

标签: php utf-8 ascii html-email quoted-printable


【解决方案1】:

我的猜测是,因为这是一个不应该存在的结束“tr”(您后面还有另一个),所以一些友好的 html 解析器正在“帮助”您,将标签从标记更改为一些普通字符串。

另一个想法:

请看这里:https://support.sendgrid.com/hc/en-us/articles/200182068-HTML-Formatting-Issues

  1. 某些邮件客户端(例如 Outlook 和 Thunderbird)似乎会在每一行插入双倍间距换行符。原因是 MIME 中的 'content-transfer-encoding' 设置为 'quoted-printable' 它将回车换行 (CRLF) 换行符添加到源 电子邮件的内容是这些邮件解释的字符 客户。要缓解此问题,请执行以下操作:

一个。如果您可以自定义电子邮件的 MIME 设置,请设置 'Content-Transfer-Encoding' 到 '7bit' 而不是 'Quoted-Printable'。

b.确保您的内容遵循项目的行长限制 2 以上。

我想知道是否有什么东西在你的标签中放置了一个换行符,导致它不可读,然后浏览器正在添加一个额外的作为替换。

您可以试试这个:将“Content-Transfer-Encoding”更改为“7bit”还是完全省略?

【讨论】:

  • 您指的是 输出(如电子邮件中所示)。发送之前的 HTML 在语法上是正确的,并且其中没有额外的 &lt;/tr&gt;。有东西在插入它。
  • 我会感到惊讶,但是 - 你能张贴整张桌子吗?我确信里面一定有一些额外的标签,当然,我可能是错的。
  • 我发布了用于生成表格的代码。如您所见,每一行基本上都是硬编码的。
  • 如果您的 HTML 标签没有正确平衡,浏览器或电子邮件客户端中的 HTML 解析器将尝试修复问题。
  • 我坚信我的 HTML 是平衡的——生成它的 PHP 代码在问题的末尾,但我很确定它是干净的。
【解决方案2】:

问题可能是由于您插入的值中有特殊的 HTML 字符。当您在 HTML 中插入随机文本并且不希望它被解释为 HTML 时,您应该使用 htmlentitieshtmlspecialchars 对其进行编码:

foreach ($indicesServer as $arg) {
    if (isset($_SERVER[$arg])) {
        $table .= '<tr><td>'.$arg.'</td><td>' . htmlentities($_SERVER[$arg]) . '</td></tr>' ;
    } else {
        $table .= '<tr><td>'.$arg.'</td><td>-</td></tr>' ;
    }
}

另一种可能是你的行对于邮件软件来说太长了。尝试在每个表格行的末尾添加"\n"

$table .= '<tr><td>'.$arg.'</td><td>' . htmlentities($_SERVER[$arg]) . "</td></tr>'."\n" ;

【讨论】:

  • 谢谢。我只是按照建议包装了所有 PHP 输出,但没有修复它。
  • 我怀疑问题不在于 PHP,它发生在邮件软件中,就像引用可打印的东西正在删除它后面的字符时一样。
  • 尝试在每个表格行之后添加换行符,就像我更新的答案一样。
  • 尝试了换行符。没有变化。
  • 我很确定您的脚本中没有任何内容这样做。如果您将消息写入文件而不是作为邮件发送,您会看到随机的 HTML 吗?这一定是在邮件传输中发生的。
猜你喜欢
  • 2017-12-07
  • 2013-04-18
  • 1970-01-01
  • 2016-10-18
  • 2011-01-31
  • 1970-01-01
  • 1970-01-01
  • 2015-06-18
  • 1970-01-01
相关资源
最近更新 更多