0

我正在为 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 和其他网络客户端是如何做到的?很高兴研究客户端解决方案,例如 Javascript/jQuery 和 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(我的代码略有不同,但具有相同的设计和输出)

4

3 回答 3

0

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

于 2012-07-17T08:31:08.437 回答
0

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

于 2012-07-17T08:31:40.180 回答
0

在这里尝试一下,使用 domDocument 提取每条消息的正文标记之间的内容:

<?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

希望能帮助到你

于 2012-07-17T09:17:01.050 回答