在另一个内容中包含完整的HTML页面

时间:2012-07-17 08:25:54

标签: php html email imap

我正在为gmail整理一个基本的只读客户端,我成功地通过imap(在PHP中)发送电子邮件并存储它们但是我在浏览器中显示它们时遇到了一些问题。

大多数电子邮件都是完整的html网页<html><title>Your Mail</title><body>etc...</body></html>,这通常会导致电子邮件显示在其中的根html网页破损。

例如,您经常以

结束
<html>
<title>Read only mail>
<body>
<h1>Your mail:</h1>
<html><title>An email from steve</title><style>html {background-color=red;}</style>
<body>It's a read email! (get it?)</body></html>
<html><title>An email from james</title><style>body {background-color=green;}</style>
<body>I like green things, save the planet!</body></html>
More mail etc...
</body>
</html>

这不是完全有效的HTML,但主要问题是电子邮件的CSS会影响页面上的所有其他元素,我最好的想法是以某种方式用PHP制作iframe(这可能没有进一步的请求),或者以某种方式从文档中删除所有CSS和HTML。

有谁知道如何解决这个问题? gmail和其他Web客户端如何做到这一点? 很高兴看到客户端解决方案,如Javascript / jQuery&amp; Ajax的

感谢您的时间,

-

目前邮件只是输出:

/* connect */
$inbox = imap_open($hostname,$username,$password) or die(imap_last_error());

$emails = imap_search($inbox,'ALL');
if($emails) {

  /* begin output var */
  $output = '';

  /* put the newest emails on top */
  rsort($emails);

  /* for every email... */
  foreach($emails as $email_number) {

    /* get information specific to this email */
    $overview = imap_fetch_overview($inbox,$email_number,0);
    $message = imap_fetchbody($inbox,$email_number,2);

    /* output the email header information */
    $output.= '<div class="toggler '.($overview[0]->seen ? 'read' : 'unread').'">';
    $output.= '<span class="subject">'.$overview[0]->subject.'</span> ';
    $output.= '<span class="from">'.$overview[0]->from.'</span>';
    $output.= '<span class="date">on '.$overview[0]->date.'</span>';
    $output.= '</div>';

    /* output the email body */
    $output.= '<div class="body">'.$message.'</div>';
  }

  echo $output;
} 

/* close the connection */
imap_close($inbox)

取自http://davidwalsh.name/gmail-php-imap(我的代码略有不同,但设计和输出相同)

3 个答案:

答案 0 :(得分:0)

你为什么不挑选你想要保留的元素,比如身体本身通过php并放弃其余部分?您当然需要一个开关来为一组基本的电子邮件内容布局应用不同的规则:但您可以自由地为每个布局实现特定且可靠的规则。

答案 1 :(得分:0)

您可以使用iframe显示消息,或使用正则表达式服务器端抓取body标签内的文本或使用dom客户端抓取body元素。

答案 2 :(得分:0)

在这里试试这个,用domDocument提取每条消息的body标签之间的内容:

<?php set_time_limit(0); ?>

<!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>You have mail</title>
</head>

<body>

<?php
/* connect */
$hostname = '{imap.gmail.com:993/imap/ssl}INBOX';
$username = '';
$password = '';
$inbox = imap_open($hostname,$username,$password) or die(imap_last_error());

$emails = imap_search($inbox,'ALL');
if($emails){

    /* begin output var */
    $output = '';

    /* put the newest emails on top */
    rsort($emails);

    /* for every email... */
    foreach($emails as $email_number) {

        /* get information specific to this email */
        $overview = imap_fetch_overview($inbox, $email_number, 0);
        $message = imap_fetchbody($inbox, $email_number, 2);

        /* output the email header information */
        $output.= '<div class="toggler'.($overview[0]->seen ? 'read' : 'unread').'">';
        $output.= '<span class="subject">'.$overview[0]->subject.'</span> ';
        $output.= '<span class="from">'.$overview[0]->from.'</span>';
        $output.= '<span class="date">on '.$overview[0]->date.'</span>';
        $output.= '</div>';

        /* output only the email body */
        $dom = new DOMDocument();
        libxml_use_internal_errors(true);
        $dom->loadHTML($message);
        $body = $dom->getElementsByTagName("body")->item(0);
        if ($body !== null) {
            for ($n = $body->firstChild; $n !== null; $n = $n->nextSibling) {
                $body = simplexml_import_dom($n)->asXML();
            }
        }
        $output.= '<div id="body">'.$body.'</div>';
    }

    echo $output.'
</body>
</html>';
}

/* close the connection */
imap_close($inbox);
?>

如果您只想要电子邮件的纯文本部分(这也可能包含多部分边界),请回答您的其他问题

使用$message = imap_fetchbody($inbox, $email_number, 1);注意1

希望有所帮助