【问题标题】:gmail does not render html in emailgmail 不会在电子邮件中呈现 html
【发布时间】:2014-03-20 18:27:06
【问题描述】:

我将用一个非常基本的例子再试一次。当我使用 PHP 向电子邮件客户端发送电子邮件时,除了 gmail,我没有任何问题。当我在 gmail 中查看电子邮件时,我看到的只是邮件的代码。 Gmail 不显示 HTML。它只是显示代码。这是我的脚本:

<?php
$to = "someone@gmail.com";
$subject = "Test HTML E-mail";
$random_hash = md5(date("r", time()));
$mID = md5($to);
$headers = "From: admin@yellowcas.com" . "\n" . "Reply-To: admin@yellowcas.com" . "\n";
$headers .= "Errors-To: someone@yahoo.com" . "\n";
$headers .= "MIME-Version: 1.0" . "\n";
$headers .= "Content-Type: multipart/alternative; boundary=". $random_hash ." ; Message-ID: <" . $mID . ">" . "\n"; 
ob_start();
?>
--<?php echo $random_hash; ?> 
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hello, Tom!!! 
This is simple text email message.

--<?php echo $random_hash; ?> 
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 7bit

<!doctype html>
<head>
<title>Untitled Document</title>
</head>
<body>
<h2>Hello, Tom!</h2>
<p>This is something with <strong>HTML</strong> formatting.</p>
</body>
</html>

--<?php echo $random_hash; ?>-- 

<?php
$message = ob_get_clean();
$mail_sent = @mail( $to, $subject, $message, $headers );
echo $mail_sent ? "Mail sent" : "Mail failed";
?>

我试过这个没有 DOCTYPE 和 DOCTYPE 的脚本。我不相信 HTML 有什么问题。我相信 gmail 出于某种原因无法识别边界字符串。这是我打开电子邮件时看到的内容:

--111f3d21df6a6eb40a42e9337a600c21
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hello, Tom!!!
This is simple text email message.

--111f3d21df6a6eb40a42e9337a600c21
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 7bit

<!doctype html>
<head>
<title>Untitled Document</title>
</head>
<body>
<h2>Hello, Tom!</h2>
<p>This is something with <strong>HTML</strong> formatting.</p>
</body>
</html>

--111f3d21df6a6eb40a42e9337a600c21--

谁能告诉我为什么gmail呈现整个消息而不是编码HTML?好像gmail无法识别边界字符串。我该如何解决这个问题?

顺便说一句,是的,这是我在互联网上找到的一个基本的 PHP 电子邮件脚本。我做了一些修改,但它仍然无法在 gmail 中工作。所有其他电子邮件客户端都可以正常显示。 请帮忙!我无计可施。谢谢。

当我在 Fred -ii- 提交的代码示例中添加 $headers 行时,gmail 呈现了 HTML,但它仍然显示边界字符串和纯文本消息。这就是电子邮件的样子:

--f8451c07b6649388e8938cfa12ea21e6 内容类型:文本/纯文本; charset=iso-8859-1 内容传输编码:7bit 你好,格雷格!!!这是简单的文本电子邮件。 --f8451c07b6649388e8938cfa12ea21e6 内容类型:文本/html; charset=iso-8859-1 内容传输编码:7bit

你好,汤姆!

这是 HTML 格式的东西。 --f8451c07b6649388e8938cfa12ea21e6--

我希望结果是正确的。

【问题讨论】:

  • 根据php.net/mail,您的初始标题需要在$headers .= "MIME-Version: 1.0" . "\n"; 正下方包含$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
  • 停止 mail() 使用 php mailer 或 swiftmailer
  • @Fred -ii 我只是试着把它放在那里。问题是这是一个多部分消息。它有一个纯文本部分和一个 html 部分。我还被告知 gmail 不会接受 \r 字符。它会导致插入额外的行。这就是为什么我的代码中没有任何内容。
  • Gmail 接受 \r 字符。我在所有脚本中都使用\r\n,并且所有电子邮件客户端都可以正常使用,包括Gmail。我什至在$headers .= "MIME-Version: 1.0" . "\r\n"; 中使用它测试了我的答案,结果很好。
  • @Fred -ii- 这是我看到的帖子,说不要在代码中使用 \r。 stackoverflow.com/questions/10327354/…

标签: php html email gmail


【解决方案1】:

好吧,我只需添加这三行标题就可以了,所以试试看告诉我

$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";

// More headers
$headers .= 'From: <example@gmail.com>' . "\r\n";

【讨论】:

    【解决方案2】:

    编辑#4

    这是另一个不错的版本,似乎更易于使用:

    <?php
    //define the receiver of the email
    $to = 'email@example.com';
    //define the subject of the email
    $subject = 'Test HTML email';
     
    // Generate a random boundary string
    $mime_boundary = '_x'.sha1(time()).'x';
     
    // Using the heredoc syntax to declare the headers
    $headers = <<<HEADERS
    From: Test <email@example.com>
    MIME-Version: 1.0
    Content-Type: multipart/alternative;
     boundary="PHP-alt$mime_boundary"
    HEADERS;
     
    // Use our boundary string to create plain text and HTML versions
    $message = <<<MESSAGE
    --PHP-alt$mime_boundary
    Content-Type: text/plain; charset="iso-8859-1"
    Content-Transfer-Encoding: 7bit
     
    This Is a Plain Text Email
     
    This message has no HTML. http://www.google.com
     
    --PHP-alt$mime_boundary
    Content-type: text/html; charset=iso-8859-1
    Content-Transfer-Encoding: 7bit
     
    <html>
    <body>
    <h1>This Is an HTML Email</h1>
    <p>
    This message is composed in <a href="http://www.google.com">GOOGLE, click here</a>.
    </p>
    </body>
    </html>
    --PHP-alt$mime_boundary--
    MESSAGE;
     
    // Send the message
    if(!mail($to, $subject, $message, $headers))
    {
    // If the mail function fails, return an error message
    echo "Something went wrong!";
    }
    else
    {
    // Return a success message if nothing went wrong
    echo "Message sent successfully. Check your email!";
    }
    ?>
    

    编辑 3

    另一种经过测试的方法:(目前为止更好的方法)

    <?php
    
    function send_email(
    
    $to='email@example.com', 
    $from='email@example.com', 
    $subject='test', 
    $html_content='<b>HELLO in HTML bold</b>', 
    $text_content='Hi there in plain text', 
    $headers='') 
    
    { 
        # Setup mime boundary
        $mime_boundary = 'Multipart_Boundary_x'.md5(time()).'x';
    
        $headers  = "MIME-Version: 1.0\r\n";
        $headers .= "Content-Type: multipart/alternative; boundary=\"$mime_boundary\"\r\n";
        $headers .= "Content-Transfer-Encoding: 7bit\r\n";
    
        $body    = "This is a multi-part message in mime format.\n\n";
    
        # Add in plain text version
        $body   .= "--$mime_boundary\n";
        $body   .= "Content-Type: text/plain; charset=\"charset=us-ascii\"\n";
        $body   .= "Content-Transfer-Encoding: 7bit\n\n";
        $body   .= $text_content;
        $body   .= "\n\n";
    
        # Add in HTML version
        $body   .= "--$mime_boundary\n";
        $body   .= "Content-Type: text/html; charset=\"UTF-8\"\n";
        $body   .= "Content-Transfer-Encoding: 7bit\n\n";
        $body   .= $html_content;
        $body   .= "\n\n";
    
        # Attachments would go here
        # But this whole email thing should be turned into a class to more logically handle attachments, 
        # this function is fine for just dealing with html and text content.
    
        # End email
        $body   .= "--$mime_boundary--\n"; # <-- Notice trailing --, required to close email body for mime's
    
        # Finish off headers
        $headers .= "From: $from\r\n";
        $headers .= "X-Sender-IP: $_SERVER[SERVER_ADDR]\r\n";
        $headers .= 'Date: '.date('n/d/Y g:i A')."\r\n";
    
        # Mail it out
        return mail($to, $subject, $body, $headers);
    }
    send_email(); // call the function
    ?>
    

    编辑 2

    这行得通,并且只在 Gmail 中以 HTML 格式显示,所以理论上纯文本应该可以工作。

    <?php
    
    $notice_text = "This is a multi-part message in MIME format.";
    $plain_text = "This is a plain text email.\r\nIt is very cool.";
    $html_text = "<html><body>This is an <b style='color:purple'>HTML</b>" .
                 "text email.\r\nIt is very cool.</body></html>";
    
    $semi_rand = md5(time());
    $mime_boundary = "==MULTIPART_BOUNDARY_$semi_rand";
    $mime_boundary_header = chr(34) . $mime_boundary . chr(34);
    
    $to = "Me <email@example.com>";
    // $bcc = "You <you@you.com>, Them <them@them.com>";
    $from = "Him <another@example.com>";
    $subject = "My Email";
    
    $body = "$notice_text
    
    --$mime_boundary
    Content-Type: text/plain; charset=us-ascii
    Content-Transfer-Encoding: 7bit
    
    $plain_text
    
    --$mime_boundary
    Content-Type: text/html; charset=us-ascii
    Content-Transfer-Encoding: 7bit
    
    $html_text
    
    --$mime_boundary--";
    
    if (@mail($to, $subject, $body, 
        "From: " . $from . "\n" . 
        "bcc: " . $bcc . "\n" . 
        "MIME-Version: 1.0\n" . 
        "Content-Type: multipart/alternative;\n" . 
        "     boundary=" . $mime_boundary_header))
        echo "Email sent successfully.";
    else
        echo "Email NOT sent successfully!";
    
    ?>
    

    编辑 1

    试试这个版本:(测试没有任何额外的代码)

    <?php
    $to = "someone@gmail.com";
    $subject = "Test HTML E-mail";
    
    $headers = "From: admin@yellowcas.com" . "\n" . "Reply-To: admin@yellowcas.com" . "\r\n";
    $headers .= "MIME-Version: 1.0\r\n";
    
    //unique boundary
    $boundary = uniqid("HTMLDEMO");
    
    //tell e-mail client this e-mail contains//alternate versions
    $headers .= "Content-Type: multipart/mixed; boundary = $boundary\r\n\r\n";
    
    //plain text version of message
    $body = "--$boundary\r\n" .
       "Content-Type: text/plain; charset=ISO-8859-1\r\n" .
       "Content-Transfer-Encoding: base64\r\n\r\n";
    $body .= chunk_split(base64_encode("
    
    Hello, Tom!!! 
    This is simple text email message.
    
    "));
    
    //HTML version of message
    $body .= "--$boundary\r\n" .
       "Content-Type: text/html; charset=ISO-8859-1\r\n" .
       "Content-Transfer-Encoding: base64\r\n\r\n";
    $body .= chunk_split(base64_encode("
    
    <!doctype html>
    <head>
    <title>Untitled Document</title>
    </head>
    <body>
    <h2>Hello, Tom!</h2>
    <p>This is something with <strong>HTML</strong> formatting.</p>
    </body>
    </html>
    
    
    "));
    ob_start();
    
    ?>
    
    <?php
    $message = ob_get_clean();
    $mail_sent = mail( $to, $subject, $body, $headers );
    echo $mail_sent ? "Mail sent" : "Mail failed";
    ?>
    

    您需要在初始标题中使用以下内容:

    $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
    

    下面:

    $headers .= "MIME-Version: 1.0" . "\n";
    

    根据the manual on PHP.net

    已测试(以 HTML 而非代码的形式成功发送到我的 Gmail)

    <?php
    $to = "someone@gmail.com";
    $subject = "Test HTML E-mail";
    $random_hash = md5(date("r", time()));
    $mID = md5($to);
    $headers = "From: admin@yellowcas.com" . "\n" . "Reply-To: admin@yellowcas.com" . "\n";
    $headers .= "Errors-To: someone@yahoo.com" . "\n";
    $headers .= "MIME-Version: 1.0" . "\n";
    $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
    $headers .= "Content-Type: multipart/alternative; boundary=". $random_hash ." ; Message-ID: <" . $mID . ">" . "\n"; 
    ob_start();
    ?>
    
    // rest of code below...
    

    【讨论】:

    • 让我试试这个。我将复制并粘贴它,就像你在这里一样。当然,我会将电子邮件地址更改为我的。我会让你知道会发生什么。谢谢。
    • 我得到了要呈现的 html,但我仍然看到边界字符串以及明文消息。
    • 查看我的编辑 我稍微改了一下,但它可以工作。 @GrG
    • 这段代码比我的代码好用。它现在显示没有边界字符串的消息。唯一的问题是它同时显示纯文本和 HTML 文本。有什么想法吗?
    • 参见 Edit 3 它只显示 HTML,但是当您查看完整的标题时,它将显示 Hi there in plain text @GrG
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-03
    • 2016-05-15
    • 1970-01-01
    • 2015-09-24
    • 2019-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多