如何在 perl 中发送 HTML/纯文本邮件

Posted

技术标签:

【中文标题】如何在 perl 中发送 HTML/纯文本邮件【英文标题】:how to send HTML/Plain Text mail in perl 【发布时间】:2015-06-15 13:23:04 【问题描述】:

我是 perl 语言的新手,我想在同一封电子邮件中发送纯文本文件和 html 文本的内容。我在哪里获取文本文件的文件内容,但我的 HTML 文本不起作用,即我的电子邮件中不是一个粗体句子。有人可以解释我的html标签如何工作。下面是我的完整代码。 P.S:当我删除打印 MAIL "MIME-Version: 1.0" 行时,我的 html 标记工作但文本文件不工作(不逐行打印)。

use MIME::Lite;
my $HOME        ='/apps/stephen/data';
my $FILE        ="$HOME/LOG.txt";
my @HTML        =();


 push(@HTML,"<b>To send the content of a file in email</b><br>\12");
 push(@HTML,`cat $FILE`);

&sendMail;


sub sendMail

$sub="TEST";
$from='ABC@ABC.com';
$to='ABC@ABC.com';
open(MAIL, "|/usr/lib/sendmail -t");
        print MAIL "From: $from \12"; print MAIL "To: $to \12";print    MAIL "Cc: $Cc \12";
        print MAIL "Subject: $sub \12";
        print MAIL "MIME-Version: 1.0" ;
        print MAIL "Content-Type: text/html \12";
        print MAIL "Content-Disposition:inline \12";
        print MAIL @HTML;
    close(MAIL);

【问题讨论】:

好的,我删除了 sendmail,但它仍然像以前一样工作。 嗯?你删除了什么?你有use MIME::Lite,但你没有使用这个包中的任何函数;取而代之的是,您煞费苦心地手动构建了一个(n 个不正确的)MIME 结构。 【参考方案1】:

您正准备use MIME::Lite,但随后您忘记了这一切并尝试手动拼凑一个 MIME 结构。即使您确切地知道自己在做什么,这也是痛苦且容易出错的;您绝对应该使用一组合适的库函数,以保持您的代码简单易读,并专注于实际任务。

MIME::Lite documentation 准确地展示了如何做到这一点,就在介绍的第二个示例中。

适应您的存根代码,

use MIME::Lite;

use strict;   # always
use warnings; # always

### Create a new multipart message:
$msg = MIME::Lite->new(
    From    => 'ABC@ABC.com',
    To      => 'ABC@ABC.com',
    #Cc      => 'some@other.com, some@more.com',
    Subject => 'TEST your blood pressure with some CAPS LOCK torture',
    Type    => 'multipart/mixed'
);

### Add parts (each "attach" has same arguments as "new"):
$msg->attach(
    Type     => 'text/html',
    Data     => join ('\n', '<b>To see the content of a file in email</b><br/>',
             '<strong><blink><a href="cid:LOG.txt">click here</a></blink></strong>')
);
$msg->attach(
    Type     => 'text/plain',
    Path     => '/apps/stephen/data/LOG.txt',
    Filename => 'LOG.txt',
    Disposition => 'attachment'
);
$msg->send();

【讨论】:

非常感谢!!它工作我得到一个附件和 html 正文。现在,我想要的不是附件,而是电子邮件正文中的内容,就在 html 文本下方。 然后发送一个 HTML 部分并将纯文本嵌入到一对&lt;pre&gt;...&lt;/pre&gt; 标签中。 在同一封电子邮件中发送 HTML 和纯文本正文,但仅根据邮件客户端显示适当的正文,将 new() 中的类型设置为 'multipart/alternative' 然后添加“text/plain”正文,然后是“text/html”正文。 @user1663987 multipart/alternative 中的 MIME 部分的顺序并不重要。正如在Steffen Ulrich's answer 的 cmets 中所讨论的(上方或下方,取决于您查看此页面的方式),用户的偏好和客户端软件的逻辑决定了显示的内容。 @tripleee 我遇到过客户端,如果是第二个,它们将始终显示文本/纯文本【参考方案2】:

这并不是 Perl 所特有的。 如果您想发送具有相同数据的替代表示的邮件,您必须使用 multipart/alternative,即

Mime-Version: 1.0
Content-type: multipart/alternative; boundary=foobar

--foobar
Content-type: text/plain

Plain text here
--foobar
Content-type: text/html

<p>HTML text here</p>
--foobar--

这样邮件程序将获得最好的表示。由于手动构建此类邮件可能很困难,因此您最好使用Email:MIME、MIME::Lite 或MIME::tools 等模块。

P.S:当我删除打印 MAIL "MIME-Version: 1.0" 行时,我的 html 标记工作但文本文件不工作(不逐行打印)。

难怪你忘记了行尾,也就是说,而不是

    print MAIL "MIME-Version: 1.0" ;

应该是

    print MAIL "MIME-Version: 1.0\n" ;

除此之外,使用\n 而不是\12 更清楚。

如果您坚持手动创建 MIME 消息,请仔细查看相关标准,另请参阅 http://en.wikipedia.org/wiki/MIME。值得注意的是,Mail/Mime 标题和正文之间必须有一个空行,并且不需要在每个标题行的末尾添加空格。

【讨论】:

“最佳”通常不正确。如果邮件客户端只能显示 text/plain,那么它将选择 text/plain。如果用户指定他们更喜欢 text/plain,那么它将选择 text/plain。许多纯 HTML 邮件作者希望它不以这种方式工作,但它就是这样工作的,而且它应该是这样工作的。 "best" 是从邮件客户端的角度来看的。如果用户要求在 HTML 上显示纯文本,那么纯文本是最好的。是的,许多作者甚至一些邮件客户端都没有正确处理这种情况,例如以纯文本和 HTML 格式发送不同的内容,或者仅将附件添加到 HTML 部分 (AppleMail)。 那我们基本同意。也许还提到,headers 和 body 之间需要有一个空行,这也是 OP 代码中的失败。 此外,其目的显然是附加文件,尽管 OP 忘记对代码顶部附近定义的文本文件进行实际操作。

以上是关于如何在 perl 中发送 HTML/纯文本邮件的主要内容,如果未能解决你的问题,请参考以下文章

如何发送带有 HTML 标签的电子邮件,而不是 C# 中的 HTML 纯文本

如何发送包含纯文本和 HTML 文本的邮件,以便每个邮件阅读器都可以选择适合它的格式?

使用 Pear Mail 发送纯文本和 html 电子邮件(如何设置“Content-Type”并正确使用边界)

带有纯文本部分、html 部分和附件的电子邮件

flask 电子邮件进阶实践-用模板发送163邮件

在使用 email/smtplib 发送的邮件中结合纯文本和 HTML