首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP、HTML、Email -相等号电子邮件正在被转换成不同的字符。

PHP、HTML、Email -相等号电子邮件正在被转换成不同的字符。
EN

Stack Overflow用户
提问于 2016-07-12 08:51:09
回答 1查看 2.9K关注 0票数 4

设置.

我是通过PHP发送电子邮件,以通常的方式..。

代码块0

代码语言:javascript
复制
mail('', $subject, $message, $headers);

..。通过以下内容设置:

代码块1

代码语言:javascript
复制
$boundary = uniqid('np');
$message = '';

$subject = 'Email Subject';

$headers = "MIME-Version: 1.0\r\n";
$headers .= "From: SURL <noreply@someurl.com>\r\n";
$headers .= "To: ".$email."\r\n";

$headers .= "Content-Type: multipart/alternative;boundary=" . $boundary . "\r\n";

// Plain Text
$message .= "Content-Type: text/plain; charset=utf-8\r\n";
$message .= "Content-Transfer-Encoding: 7bit\r\n\r\n";

$message .= 'Hi, you handsome SOB!!
             \n\n
             We have ...
             /n/n                
             And ...
             \n\n
             http://someurl.com/.../.../?a=' . $var1 . '&b=' . $var2;

$message .= "\r\n\r\n--" . $boundary . "\r\n";

// HTML
$message .= "Content-Type: text/html; charset=utf-8\r\n";
$message .= "Content-Transfer-Encoding: quoted-printable\r\n\r\n";

$message .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

            <html xmlns="http://www.w3.org/1999/xhtml">

            <head>

            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

            <title>Some Title</title>

            <style type="text/css">
              ... Lots of styles...
            </style>

            </head>
            <body>

            <div class="message_container">
              <div class="message_logo"></div>

              <div class="message_leading_line">
                Hi, you handsome SOB!!
              </div> <!-- end message_leading_line -->

              <div class="message_top_content">
                We have ...
                <br/>
                And ... 
                <a href="http://someurl.com/.../.../?a=' . $var1 . '&b=' . $var2 . '" >visit this link</a>.
              </div> <!-- end message_top_content -->

              <div class="message_bottom_content">
                If link doesn\'t work, copy and paste...
                <pre>http://someurl.com/.../.../?a=' . $var1 . '&b=' . $var2 . '</pre>
              </div> <!-- end message_bottom_content -->

            </div> <!-- end message_container -->

            </body>
            </html>';

$message .= "\r\n\r\n--" . $boundary . "--";

这一切都很好。这封电子邮件发送时没有任何问题。查看电子邮件,它是正确的样式,一切都应该在哪里--包括所有动态添加的内容。

到目前为止行为.

到目前为止,我已经尝试过许多测试用例,而且所有的测试用例都按照缩进的方式发送。造型等等。

其中一个成功案例是:

代码块3-1,3-2

代码语言:javascript
复制
$var1 = '4pD9051LsVtQu96pLBH41019v28T0o4Z2I3U6urs';
$var2 = 'verPkBE415i447V6R9o';

..。所以电子邮件中的链接是:

代码语言:javascript
复制
http://someurl.com/.../.../?a=4pD9051LsVtQu96pLBH41019v28T0o4Z2I3U6urs&b=verPkBE415i447V6R9o

邮件发送正确,链接显示正确,链接正常工作(点击并复制/粘贴)。太棒了!

问题.

最近的一次测试:

代码块4-1 4-2

代码语言:javascript
复制
$var1 = '73jbzUN90j27ME5N6W4jh24o992V91m3R632Hlu0';
$var2 = 'avr1owgJAAB3h4l1brw';

..。因此,这种联系是:

代码语言:javascript
复制
http://someurl.com/.../.../?a=73jbzUN90j27ME5N6W4jh24o992V91m3R632Hlu0&b= avr1owgJAAB3h4l1brw

这一次,电子邮件.正确吗?寄来时没有明显的问题。乍一看,一切都如出一辙。所有的造型都是它应该做的,所有的内容都在它需要的地方。

注意:显示的Gmail版本是后一个版本,删除了所有标记并以纯文本形式显示。仍然出现了错误的URL。

但是,仔细检查一下,电子邮件客户端(Apple Mail和Gmail,这两个单独的帐户)中显示的链接是:

代码语言:javascript
复制
http://someurl.com/.../.../?asjbzUN90j27ME5N6W4jh24o992V91m3R632Hlu0&b=ver1owgJAAB3h4l1brw

区别就在问号后面。应该是?a=73jb的是?asjb。点击链接不起作用,复制和粘贴也不起作用。有明显的原因-嗯!

The Quirk?

奇怪的是,如果查看相同的电子邮件作为源(查看->消息->原始源),链接完全是他们应该是.

原始来源1

代码语言:javascript
复制
To: 
Subject: Email Subject
X-PHP-Originating-Script: 2181:email.php
MIME-Version: 1.0
From:  SURL <noreply@someurl.com>
To: email@email.com
Content-Type: multipart/alternative;boundary=np57849efa2a13b
X-Identified-User: {:box895.bluehost.com:...:...e.com} {sentby:program running on server}

Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit

Hi, you handsome SOB!!
\n\n
We have ...
/n/n                 
And ...
\n\n
http://someurl.com/.../.../?a=73jbzUN90j27ME5N6W4jh24o992V91m3R632Hlu0&b=avr1owgJAAB3h4l1brw

--np57849efa2a13b
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Some Title</title>

<style type="text/css">
... Lots of styles...
</style>

</head>
<body>

  <div class="message_container">
    <div class="message_logo"></div>

    <div class="message_leading_line">
      Hi, you handsome SOB!!
    </div> <!-- end message_leading_line -->

    <div class="message_top_content">
      We have ...
      <br/>
      And ... 
      <a href="http://someurl.com/.../.../?a=73jbzUN90j27ME5N6W4jh24o992V91m3R632Hlu0&b=avr1owgJAAB3h4l1brw" >visit this link</a>.
    </div> <!-- end message_top_content -->

    <div class="message_bottom_content">
      If link doesn\'t work, copy and paste...
      <pre>http://someurl.com/.../.../?a=73jbzUN90j27ME5N6W4jh24o992V91m3R632Hlu0&b=avr1owgJAAB3h4l1brw</pre>
    </div> <!-- end message_bottom_content -->

  </div> <!-- end message_container -->

</body>
</html>

--np57849efa2a13b--

那怎么回事?发送的数据似乎是正确的,但在非常特殊的情况下,所有的牛粪都会显示出来。为什么=73要转换为s (或者a=73转换为as.)?

我查过ASCII表HTML码了。在这两种情况下,唯一与73相关的是大写字母"i“。

编辑1

你难道不知道在发完这个问题后,我马上就发现了此HTML URL编码引用

在那里,您会发现%73s相关联。

但是,我仍然不太确定=73...是如何变成%73...的,然后变成s...的。当然,这似乎与utf-8有关。

我肯定不是第一个发邮件的人,一定有办法.

编辑2-解决方案!!

解决方案和解释太长了,所以把它作为答案发布。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-07-12 10:11:26

这一问题来自以下几个方面:

代码语言:javascript
复制
$message .= "Content-Transfer-Encoding: quoted-printable\r\n\r\n";

根据你好,‘Wiki

QP的工作方式是使用等号"=“作为转义字符。

如果您想保持quoted-printable编码,有一种方法可以避免这种情况:

..。ASCII等号(小数值61)必须用"=3D“表示。除了可打印的ASCII字符或行结束字符之外,所有字符都必须以这种方式编码。

所以台词..。

代码语言:javascript
复制
http://someurl.com/.../.../?a=3D73jbzUN90j27ME5N6W4jh24o992V91m3R632Hlu0&b=3Davr1owgJAAB3h4l1brw

..。会很好(注意到=3D)。

,但这还不够!

如果要使用quoted-printable,则需要将每个等号设置为=3D。这包括在您的标题、样式、脚本和html等中。

例如,查看来自TeamTreehouse的“忘记密码”电子邮件的前几行,该邮件还使用quoted-printable编码:

代码语言:javascript
复制
... Headers and plain-text version above ...

Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.=
w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns=3D"http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3DUTF-8">
  <title>Treehouse</title>


  <style type=3D"text/css">
    ... some styles, no equals signs ...
  </style>
</head>

<body leftmargin=3D"0" marginwidth=3D"0" topmargin=3D"0" marginheight=3D"0"=
 offset=3D"0" style=3D"-webkit-text-size-adjust: none; background: #edeff0;=
 margin: 0; padding: 0; width: 100% !important" bgcolor=3D"#edeff0">
  <center>
    <table border=3D"0" cellpadding=3D"0" cellspacing=3D"0" height=3D"100%"=
 width=3D"100%" style=3D"background: #edeff0; color: #9ba6b0; font-family: =
Helvetica,sans-serif; font-size: 14px; height: 100% !important; margin: 0; =
padding: 0; width: 100% !important" bgcolor=3D"#edeff0">

..。诸若此类。

这种编码类型的限制是:

可打印编码数据行数不得超过76个字符.为了在不改变编码文本的情况下满足这一要求,可以根据需要添加软换行。软行中断由编码行末尾的"=“组成.

这意味着原始内容可能最终看起来如下所示:

代码语言:javascript
复制
...
2wtdG91WGhKTEVZVVpoWnZsamo4IiwidiI6MSwicCI6IntcInVcIjozMDA4Nzg2NixcInZcIjox=
LFwidXJsXCI6XCJodHRwOlxcXC9cXFwvdGVhbXRyZWVob3VzZS5jb21cXFwvXCIsXCJpZFwiOlw=
iN2VlMmFmYWZiNGYwNGY5MGE2Y2NjMGExZGQwODdiMWVcIixcInVybF9pZHNcIjpbXCJlMzdmNG=
JlNDQ5NzYyY2NjZDQ5MmZjNmUyZDgwMjFhMTUxODgyM2RkXCJdfSJ9">teamtreehouse.com</=
...

如果你有合适的编码集,对解释器来说不是什么大不了的事,但对肉眼来说却不那么漂亮和容易理解。

,但为什么使用引号-可打印!?

继续我们的阅读,结果发现有些SMTP (简单邮件传输协议)有1000个字符的行限制.通过强迫你的行不超过76个字符(第76位是=),你不会因为这个特殊原因而冒电子邮件失败的风险。

你是怎么做的!?

原来,PHP有一个本机函数,就是为了这个.

代码语言:javascript
复制
quoted_printable_encode(string);

用问题中的准确的电子邮件代码进行了测试,并按照广告的方式工作!

做同样的事情(我知道,这可能很明显):

代码语言:javascript
复制
<?php 
    $var = '... some huge, long string...';

    $var2 = quoted_printable_encode($var);
?>

然后为了一个很好的视觉对比。

代码语言:javascript
复制
<html>
<body>

<?php 

    echo '<pre>' . htmlspecialchars($var) . '</pre>'; 

    echo '<br><hr><br>';

    echo '<pre>' . htmlspecialchars($var2) . '</pre>'; 

?>

</body>
</html>

注意:对于您的电子邮件(如在问题中),您只想在Content-Transfer-Encoding: quoted-printable声明之后对该部分进行编码.

代码语言:javascript
复制
$message .= "Content-Type: text/html; charset=utf-8\r\n";
$message .= "Content-Transfer-Encoding: quoted-printable\r\n\r\n";

$tmp = '<html>... long, formatted, beautiful...</html>';

$message .= quoted_printable_encode($tmp);

$message .= "\r\n\r\n--" . $boundary . "--";

加上一些毫无意义的废话,因为StackOverflow不喜欢编辑少于6个字符!愚蠢而毫无意义的限制。意味着简单的拼写错误无法纠正。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38324093

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档