电子邮件中编码的随机 HTML 个字符
Random HTML characters being encoded in emails
我正在生成一封带有 PHP 的电子邮件,输出 HTML table。大部分 table 都能顺利通过,但一些 <
和 >
字符被随机编码为 <
和 >
。它并不总是在同一个地方进行。有时它只发生在一个地方,有时根本不发生,有时在多个地方。
这是我的 table 中间的代码片段,正如我的电子邮件客户端看到的那样。请注意插入的 < /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>
< /tr>
</tr>
<tr>
<td>REQUEST_METHOD</td>
<td>POST</td>
</tr>
以及电子邮件明文部分中的同一段:(再次注意,</tr>
以某种方式被插入。)
SERVER_SOFTWARE Apache/2.2.29 (Red Hat)
SERVER_PROTOCOL HTTP/1.1 < /tr>
REQUEST_METHOD POST
发送前我在 headers 中将其设置为 UTF-8:
$headers = "MIME-Version: 1.0\r\nContent-Type: text/html; charset=UTF-8\r\nContent-Transfer-Encoding: quoted-printable";
(P.S。我之前使用 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
,但有时下一个字符会被删除!因此发生了以下情况:
<a href="http://example.com">
成为
<a href=3D"ttp://example.com">
<table cellpadding=3 cellspacing=0 border=1>
成为
<table cellpadding<ellspacingorder=3D"<tr">
我的猜测是因为那是一个不应该存在的结束 "tr"(你在它后面还有另一个),一些友好的 html 解析器是 "helping" 你从作为一些普通字符串的标签。
另一个想法:
看这里:https://support.sendgrid.com/hc/en-us/articles/200182068-HTML-Formatting-Issues
- Some mail clients, such as Outlook and Thunderbird, appear to insert double spacing line breaks at every line. The reason is that
the 'content-transfer-encoding' in MIME is set to 'quoted-printable'
which adds Carriage Return Line Feed (CRLF) line breaks to the source
content of the email which are characters interpreted by these mail
clients. To alleviate this problem, please do the following:
a. If you can customize the MIME settings for your email, set the
'Content-Transfer-Encoding' to '7bit' instead of 'Quoted-Printable.'
b. Ensure that your content follows the line length limits from item
2 above.
我想知道是否有什么东西在你的标签中放置了一个换行符,导致它不可读,然后浏览器添加了一个额外的作为替换。
你能试试这个吗:将 'Content-Transfer-Encoding' 更改为“7bit” 或完全不使用它?
问题可能是由于您插入的值中有特殊的 HTML 字符。当您在 HTML 中插入随机文本并且您不希望它被解释为 HTML 时,您应该使用 htmlentities
或 htmlspecialchars
对其进行编码:
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>' ;
}
}
另一种可能是您的线路对于邮件软件来说太长了。尝试在每个 table 行的末尾添加 "\n"
:
$table .= '<tr><td>'.$arg.'</td><td>' . htmlentities($_SERVER[$arg]) . "</td></tr>'."\n" ;
我正在生成一封带有 PHP 的电子邮件,输出 HTML table。大部分 table 都能顺利通过,但一些 <
和 >
字符被随机编码为 <
和 >
。它并不总是在同一个地方进行。有时它只发生在一个地方,有时根本不发生,有时在多个地方。
这是我的 table 中间的代码片段,正如我的电子邮件客户端看到的那样。请注意插入的 < /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>
< /tr>
</tr>
<tr>
<td>REQUEST_METHOD</td>
<td>POST</td>
</tr>
以及电子邮件明文部分中的同一段:(再次注意,</tr>
以某种方式被插入。)
SERVER_SOFTWARE Apache/2.2.29 (Red Hat)
SERVER_PROTOCOL HTTP/1.1 < /tr>
REQUEST_METHOD POST
发送前我在 headers 中将其设置为 UTF-8:
$headers = "MIME-Version: 1.0\r\nContent-Type: text/html; charset=UTF-8\r\nContent-Transfer-Encoding: quoted-printable";
(P.S。我之前使用 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
,但有时下一个字符会被删除!因此发生了以下情况:
<a href="http://example.com">
成为
<a href=3D"ttp://example.com">
<table cellpadding=3 cellspacing=0 border=1>
成为
<table cellpadding<ellspacingorder=3D"<tr">
我的猜测是因为那是一个不应该存在的结束 "tr"(你在它后面还有另一个),一些友好的 html 解析器是 "helping" 你从作为一些普通字符串的标签。
另一个想法:
看这里:https://support.sendgrid.com/hc/en-us/articles/200182068-HTML-Formatting-Issues
- Some mail clients, such as Outlook and Thunderbird, appear to insert double spacing line breaks at every line. The reason is that the 'content-transfer-encoding' in MIME is set to 'quoted-printable' which adds Carriage Return Line Feed (CRLF) line breaks to the source content of the email which are characters interpreted by these mail clients. To alleviate this problem, please do the following:
a. If you can customize the MIME settings for your email, set the 'Content-Transfer-Encoding' to '7bit' instead of 'Quoted-Printable.'
b. Ensure that your content follows the line length limits from item 2 above.
我想知道是否有什么东西在你的标签中放置了一个换行符,导致它不可读,然后浏览器添加了一个额外的作为替换。
你能试试这个吗:将 'Content-Transfer-Encoding' 更改为“7bit” 或完全不使用它?
问题可能是由于您插入的值中有特殊的 HTML 字符。当您在 HTML 中插入随机文本并且您不希望它被解释为 HTML 时,您应该使用 htmlentities
或 htmlspecialchars
对其进行编码:
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>' ;
}
}
另一种可能是您的线路对于邮件软件来说太长了。尝试在每个 table 行的末尾添加 "\n"
:
$table .= '<tr><td>'.$arg.'</td><td>' . htmlentities($_SERVER[$arg]) . "</td></tr>'."\n" ;