Perl 在网站上解析和显示MIME多部分电子邮件

Perl 在网站上解析和显示MIME多部分电子邮件,perl,email,mime,cpan,template-toolkit,Perl,Email,Mime,Cpan,Template Toolkit,我有一封原始电子邮件(MIME multipart),我想在网站上显示它(例如,在iframe中,带有HTML部分和纯文本部分的选项卡,等等)。是否有任何CPAN模块或Template::Toolkit插件可以帮助我实现这一点 目前,看起来我必须用Email::MIME解析消息,然后迭代所有部分,并为所有不同的MIME类型编写一个处理程序 这是一个远大的希望,但我想知道是否有人已经做了这一切?如果我自己尝试的话,编写处理程序将是一个漫长且容易出错的过程 谢谢你的帮助。对我来说,这听起来并不难:

我有一封原始电子邮件(MIME multipart),我想在网站上显示它(例如,在iframe中,带有HTML部分和纯文本部分的选项卡,等等)。是否有任何CPAN模块或Template::Toolkit插件可以帮助我实现这一点

目前,看起来我必须用Email::MIME解析消息,然后迭代所有部分,并为所有不同的MIME类型编写一个处理程序

这是一个远大的希望,但我想知道是否有人已经做了这一切?如果我自己尝试的话,编写处理程序将是一个漫长且容易出错的过程


谢谢你的帮助。

对我来说,这听起来并不难:

use Email::MIME;
my $parsed = Email::MIME->new($message);
my @parts = $parsed->parts; # These will be Email::MIME objects, too.
print <<EOF;
<html><head><title>!</title></head><body>
EOF
for my $part (@parts) {    
    my $content_type = $parsed->content_type;
    if ($content_type eq "text/plain") {
         print "<pre>", $part->body (), "</pre>\n";
    }
    elsif ($content_type eq "text/html") {
        print $part->body ();
    }        
    # Handle some more cases here
}
print <<EOF;
</body></html>
EOF
使用Email::MIME;
my$parsed=Email::MIME->new($message);
我的@parts=$parsed->parts;#这些对象也将是Email::MIME对象。
打印正文(),“\n”;
}
elsif($content\u type eq“text/html”){
打印$part->body();
}        
#在这里处理更多的案件
}

打印重用现有的完整软件。具有出色的MIME支持。

事实上,我几个月前刚刚处理过这个问题。我为我工作的产品添加了电子邮件功能,包括发送和接收。第一部分是向用户发送提醒,但我们不想为我们的客户管理员管理回退,我们决定使用一个邮件收件箱,管理员可以在没有我们的情况下看到回退和回复,管理员可以在需要时调整电子邮件地址

因此,我们接受发送到我们关注的收件箱的所有电子邮件。我们使用将电子邮件与用户关联,并将整个电子邮件按原样存储在数据库中。然后,当管理员请求查看电子邮件时,我们必须解析电子邮件

我的第一次尝试与先前的回答非常相似。如果其中一个部分是html,则显示它。如果是文本,则显示它。否则,显示原始电子邮件。这个问题很快就解决了,有几封电子邮件不是由sendmail生成的。Outlook、Exchange和其他一些电子邮件系统不这样做,它们使用多部分发送电子邮件。经过大量的挖掘和咒骂,我发现这个问题似乎没有很好的记录。通过查看MHonArc和阅读RFC(RFC2045和RFC2046),我确定了以下解决方案。我决定不使用MHonArc,因为我无法轻松恢复解析和显示功能。我不认为这是完美的,但我们使用它已经足够好了

首先,获取消息并使用Email::MIME解析它。然后调用一个名为get_part的函数,该函数包含Email::MIME通过->parts()提供的部件数组

get_part,对于传递的每个部分,对内容类型进行解码,在哈希中查找,如果存在,则调用与该内容类型关联的函数。如果解码器能给我们一些东西,把它放在一个结果数组上

最后一块拼图是这个解码器阵列。基本上,它定义了我可以处理的内容类型:

  • text/html
  • 文本/纯文本
  • 消息/传递状态,实际上也是纯文本
  • 多部分/混合
  • 多部分/相关的
  • 多部分/备选方案
非多部分部分我按原样返回。对于mixed、related和alternative,我只调用MIME节点上的get_部分并返回结果。因为alternative是特殊的,所以它在调用get_parts之后有一些额外的代码。如果它有一个html部分,它将只返回html,或者它将只返回它有一个文本部分的文本部分。如果两者都没有,它将不会返回任何有效的内容

有效内容类型散列的优点是,我可以根据需要轻松地为更多部分添加逻辑。当你完成这些部分的时候,你应该有一个你所关心的所有内容的数组


我还要提一件事。作为其中的一部分,我们创建了一个单独的域来实际服务这些消息。管理员工作的主域将拒绝提供消息,并将浏览器重定向到我们的用户内容域。第二个域将只提供用户内容。这是为了帮助浏览器正确地沙箱内容远离我们的主域。请参阅同源策略()

但您需要对其进行消毒。你不想让电子邮件将任意JS注入你的站点!更不用说在文本/普通部分对实体进行编码了。对我来说,这仍然不是一项大工作。实体就是这么难:
s/([&])/“&#”.ord($1)。”/ge
和通过
HTML::scriber
进行HTML清理。这就是我计划做的,但我担心的是“在这里处理更多的案例”。我对MIME multipart和所有不同的类型了解不够,所以不会把它搞砸。我想将附件显示为回形针等。。。但也许我太偏执了。。。谢谢你的帮助。回答得很好。代码中有几个小错误。应该是$content\u type=$part->content\u type(未解析->content\u type)。另外,使用正则表达式来匹配content\u type($content\u type=~m/text\/plain/),而不是字符串比较,因为可能会有一个charset.Dupe-of-Thanke-daxim,我以前查看时没有发现。看来我还是得用Email::MIME了。这可能正是我想要的。将调查。。。谢谢