如何发送带有变异元音的 Perl Mail::Sender? [复制]

Posted

技术标签:

【中文标题】如何发送带有变异元音的 Perl Mail::Sender? [复制]【英文标题】:How to send Perl Mail::Sender with mutated vowel? [duplicate] 【发布时间】:2016-09-01 15:52:54 【问题描述】:

我创建了一个使用 Mail::Sender 发送邮件的 Perl 脚本。一切都很好 - 通常它可以工作。

一些小问题。

主题和发件人姓名(姓名而非电子邮件地址)包含变异元音(德语特殊字符)。

我已经搜索了一些提示,但没有找到任何提示。

是否有任何示例如何使用此功能,或者有人可以给我一个提示如何完成此操作。

编辑

我已经这样做了:

ref ($av_tmp_MAIL = new Mail::Sender 
 
    from => "$av_loc_FROME ($av_loc_FROMN)",
    replyto => $av_loc_FROME,
    to => @av_loc_TO,
    cc => @av_loc_CC,
    bcc => @av_loc_BCC,
  smtp => 'smtp.av.loc',

)
 or die "Error($av_tmp_MAIL) : $Mail::Sender::Error\n";

在“电子邮件地址(姓名)”表单中配置“发件人”部分时,您通常会在邮件客户端中获得返回,以便在表单中的发件人电子邮件地址之前放置发件人姓名:

“发件人姓名”,其中真正显示了“”。

由于我的发件人姓名有一些变异的元音(德语特殊字符)“Grundwasserfrühwarnsystem Forstinning”,我需要对这部分进行编码。

我已经尝试了所有这些变体:

#$av_loc_FROMN = Encode::encode("MIME-Q", Encode::decode_utf8($av_loc_FROMN)); # ganz seltsam mit der leerstelle
#$av_loc_FROMN = Encode::encode("MIME-Header", $av_loc_FROMN); # ganz seltsam mit der leerstelle
#$av_loc_FROMN = Encode::encode("MIME-Q", $av_loc_FROMN); # ganz schlecht
#$av_loc_FROMN = Encode::encode("MIME-B", $av_loc_FROMN); # tut es nicht

但他们都没有做到这一点。

说实话——即使阅读文档,MIME-Q 与 MIME-B 和 MIME-Header 之间的差异对我来说肯定是一个奇迹。但我想,我需要学习前 x 年才能理解。

使用时:

$av_loc_SUBJECT = Encode::encode("MIME-Q", Encode::decode_utf8($av_loc_SUBJECT));

对于邮件的主题 - 它有效。

文本是“Funktionstest Grundwasserfrühwarnsystem Forstinning”。

但总的来说,它应该适用于所有类型的文本。

编辑

我会尽量讲述背后的全部故事。

我有一个 Bash 脚本来完成这项工作。这工作正常。但是我在 Bash 中创建一封精美的电子邮件时遇到了一些问题。使用 mailx 可以工作,但代码也有一些问题。从 bash 脚本中使用 sendmail 并不容易,而且对编码也有一些顾虑。至少我经历过。

我的 Bash 脚本做了一些工作,结果通过 echo 命令写入文件。然后必须将文件的文本发送给某些收件人以防发生警报。

邮件文本文件似乎是 UTF-8 编码的,并且在某些单词中包含这些变异的元音 (Deutsche Umlaute)。

我希望使用 Perl 可以更轻松地创建邮件,并有更多的可能性来格式化电子邮件(可能是 html)。所以我想创建一个 Perl 脚本,以便从 bash 脚本中调用,其中包含一些位置参数作为移交,例如 from、to、cc、bcc、subject 和已经准备好文本的文件。

这就是我所追求的。

现在我正在寻找解决方案。

是的,它在某种程度上是生产的东西(正如您可能从您所看到的主题中想象的那样)。但这仍然是一项私人活动,也是学习 Perl 编程的一些领域,我是新手。

编辑

这不是它的工作方式;参数设置是成功的关键,但必须考虑更多的先决条件:

a) perl 脚本由 bash 脚本调用。 b) bash 脚本自然地移交参数(如 --fromn)。这些参数之一包含已经重读的元音。 c) bash 脚本将主体作为文件移交给 perl 脚本。 perl 脚本要求文件内容以 utf8 编码。

到目前为止一切顺利。但主要问题是:bash 脚本本身必须是 utf8 编码的文件。只有这样,移交的参数和“echo”命令创建的主体也使用 utf8 对字符串进行编码。 !!!!!!!!!

即使在 bash 脚本中将 ENV 设置为正确的语言也无济于事。

#!/usr/bin/perl

use strict;
use warnings;
use utf8;
use warnings qw/ all FATAL /;
use Net::Domain qw(hostname hostfqdn hostdomain domainname);
use Net::Ping;
use Getopt::Long;
use autodie; # die if problem reading or writing a file
use DateTime;
use DateTime::Format::Strptime;
use DateTime::TimeZone;
use feature qwsay;

use File::Spec;
use File::Basename;

use Mail::Sender;

use Log::Logger;






#  _      __        _       _     _      
#   \    / /       (_)     | |   | |     
#  \ \  / /_ _ _ __ _  __ _| |__ | | ___ 
#   \ \/ / _` | '__| |/ _` | '_ \| |/ _ \
#    \  / (_| | |  | | (_| | |_) | |  __/
#     \/ \__,_|_|  |_|\__,_|_.__/|_|\___|
#                                        
#                                        
### variables block
our $av_std_ARG=1;
our $av_std_BASE='';
our $av_std_BIN='/usr/local/share/averlon';
our $av_std_DEBUG=0;
our $av_std_DIRNAME=dirname(__FILE__); # gibt dann u.U. nur "." wieder
our $av_std_EXIT=0;
our $av_std_FORCE=0;
our $av_std_LOGFILE='/var/log/'.hostname().'.log';
our $av_std_LOGGING=0;
our $av_std_MESSAGEFILE='/usr/local/share/averlon/av_messages.xml';
our $av_std_POSPAR;
our $av_std_RETVAL;
our $av_std_STORAGE='/ourtmp/';
our $av_std_USER;
our $av_std_TEST=0;
our $av_std_TMP='/tmp/';
our $av_std_VERBOSE=0;
our $av_std_VERSION='01.0a';

our $av_loc_FROMN="";
our $av_loc_FROME="";
our $av_loc_TO="";
our @av_loc_TO=();
our $av_loc_CC="";
our @av_loc_CC=();
our $av_loc_BCC="";
our @av_loc_BCC=();
our $av_loc_SUBJECT;
our $av_loc_FBODY;
our $av_loc_FATT="";
our @av_loc_FATT=();

###
### predefined objects
###
our $av_tmp_DT=DateTime->today();
our $av_tmp_LOGFILE;
our $av_tmp_TMP;
our $av_tmp_MAIL;

our $av_tmp_STRING;
our $av_tmp_FN;
our $av_tmp_FILE;

#dialogelemente
my $av_WINDOW;
my $av_BUTTON;
my $av_HBOX;
my $av_VBOX;
my $av_TEXTBOX1;
my $av_LABEL1;

#  ______                _   _                 
#    ____|              | | (_)                
#   |__ _   _ _ __   ___| |_ _  ___  _ __  ___ 
#    __| | | | '_ \ / __| __| |/ _ \| '_ \/ __|
#   |  | |_| | | | | (__| |_| | (_) | | | \__ \
#  _|   \__,_|_| |_|\___|\__|_|\___/|_| |_|___/
#                                              
#                                              
### functions commands block

sub av_help

    print "Benutzung:\n";
    print "/usr/local/share/averlon/av_sendmail.pl [-d, --debug] [-f, --force] [-h, --help] [-l, --logging] [-t, --test] [-v, --verbose] [-V, --version]\n";
    print "[--fromn=<sender name>] [--frome=<e-mail>] [--to=<e-mail>[,<e-mail>]]\n";
    print "[--cc=<e-mail>[,<e-mail>]] [--bcc=<e-mail>[,<e-mail>]] [--subject=<subject>]\n";
    print "[--fbody=<filename of body>] [--fatt=<filename of attachment>[,<filename of attachment>]]\n";
    print "Bedeutung der Optionen:\n";
    print "  --fromn := Name of sender\n";
    print "  --frome := e-Mail address of sender\n";
    print "  --to := comma separated list of e-mail addresses to send to\n";
    print "  --cc := comma separated list of e-mail addresses for carbon copy\n";
    print "  --bcc := comma separated list of e-mail addresses for blind copy\n";
    print "  --subject := subject to show in mail\n";
    print "  --fbody := file which contains body text\n";
    print "  --fatt := list of filenames which to attach to e-Mail\n";
    print "  -d, --debug := debugging mode\n";
    print "  -f, --force := force running\n";
    print "\tforce will omit to check dates or other conditions\n";
    print "  -h, --help := diese Information\n";
    print "  -l, --logging := log all output to file in /var/userlog/\n";
    print "\tfile is stored in /var/userlog and will have job_ as prefix and .log as suffix\n";
    print "  -t, --test := test mode on\n";
    print "  -v, --verbose := verbose logging\n";
    print "  -V, --version := Version wird ausgegeben\n";


###
### routine für das logging
###
sub av_logit

    $av_tmp_STRING=DateTime->now(time_zone=>'Europe/Berlin')->strftime('%b')
    ." ".
    DateTime->now(time_zone=>'Europe/Berlin')->strftime('%d')
    ." ".
    DateTime->now(time_zone=>'Europe/Berlin')->strftime('%H:%M:%S')
    ." ".hostname()
    ." ";
    $av_tmp_LOGFILE->log("$av_tmp_STRING"."@_");

#  _____                                _   _             
#    __ \                              | | (_)            
#   |__) | __ ___ _ __   __ _ _ __ __ _| |_ _  ___  _ __  
#    ___/ '__/ _ \ '_ \ / _` | '__/ _` | __| |/ _ \| '_ \ 
#   |   | | |  __/ |_) | (_| | | | (_| | |_| | (_) | | | |
#  _|   |_|  \___| .__/ \__,_|_|  \__,_|\__|_|\___/|_| |_|
#                | |                                      
#                |_|                                      
### preparation commands block

GetOptions (
"fromn=s" => \$av_loc_FROMN,
"frome=s" => \$av_loc_FROME,
"to=s" => \$av_loc_TO,
"cc=s" => \$av_loc_CC,
"bcc=s" => \$av_loc_BCC,
"subject=s" => \$av_loc_SUBJECT,
"fbody=s" => \$av_loc_FBODY,
"fatt=s" => \$av_loc_FATT,
"d" => \$av_std_DEBUG,    # debug
"debug"   => \$av_std_DEBUG,      # debug
"f"   => \$av_std_FORCE,      # debug
"force"   => \$av_std_FORCE,      # debug
"h"   => \&av_help,      # help
"help"   => \&av_help,      # help
"l"   => \$av_std_LOGGING,      # logging
"logging"   => \$av_std_LOGGING,      # logging
"t"   => \$av_std_TEST,      # test
"test"   => \$av_std_TEST,      # test
"v"   => \$av_std_VERBOSE,      # verbose
"verbose"  => \$av_std_VERBOSE,   # verbose
"V"   => \$av_std_VERSION,      # version
"version"  => sub  say "Version: $av_std_VERSION"     # version
)
or say ("Error in command line arguments: @ARGV");

###
### prepare logging
###
$av_tmp_LOGFILE=Log::Logger->new();
$av_tmp_LOGFILE->open_append("$av_std_LOGFILE");
&av_logit("gestartet");

$av_std_DEBUG && say "debug \$av_std_DEBUG: $av_std_DEBUG";
$av_std_DEBUG && say "debug \$av_std_FORCE: $av_std_FORCE";
$av_std_DEBUG && say "debug \$av_std_LOGGING: $av_std_LOGGING";
$av_std_DEBUG && say "debug \$av_std_TEST: $av_std_TEST";
$av_std_DEBUG && say "debug \$av_std_VERBOSE: $av_std_VERBOSE";

$av_std_DEBUG && say "debug \$av_loc_FROMN: $av_loc_FROMN";
$av_std_DEBUG && say "debug \$av_loc_FROME: $av_loc_FROME";
$av_std_DEBUG && say "debug \@av_loc_TO: $av_loc_TO";
$av_std_DEBUG && say "debug \@av_loc_CC: $av_loc_CC";
$av_std_DEBUG && say "debug \$av_loc_BCC: $av_loc_BCC";
$av_std_DEBUG && say "debug \$av_loc_SUBJECT: $av_loc_SUBJECT";
$av_std_DEBUG && say "debug \$av_loc_FBODY: $av_loc_FBODY";
$av_std_DEBUG && say "debug \@av_loc_FATT: $av_loc_FATT";

#  __  __       _         _____                  
#    \/  |     (_)       |  __ \                 
#   \  / | __ _ _ _ __   | |__) | __ ___   ___   
#   |\/| |/ _` | | '_ \  |  ___/ '__/ _ \ / __|  
#   |  | | (_| | | | | | | |   | | | (_) | (__ _ 
#  _|  |_|\__,_|_|_| |_| |_|   |_|  \___/ \___(_)
#                                                
#                                                
### main procedure

###
### prepare variables
###
if ($av_loc_TO) 

  $av_loc_TO =~s/ //u; # leerzeichen eleminieren
  push(@av_loc_TO,split(/,/,join(',',$av_loc_TO))); # hier werden die einzelnen einträge in ein array überführt; trennzeichen=,
  $av_std_DEBUG && say "debug \@av_loc_TO: @av_loc_TO";
  if ($#av_loc_TO >= 1) # wenn 1 oder mehr elemente im array vorhanden sind muss das array in einen komma-getrennten string überführt werden
   
    $av_std_DEBUG && say "debug \@av_loc_TO: @av_loc_TO";
    $av_std_DEBUG && print "$_"."\n" foreach (@av_loc_TO);
    $av_loc_TO=''; # string löschen
    foreach (@av_loc_TO)
    
        $av_loc_TO=$_.",".$av_loc_TO; #elemente des array mit komma getrennt zusammenführen - vorsicht - zum schluss ist 1 komma zuviel
    
    $av_loc_TO=substr($av_loc_TO,0,length($av_loc_TO)-1); # das letzte komma entfernen
  
  else
  
    $av_loc_TO=join(' ', @av_loc_TO);
  

else

    # To darf nicht leer sein
    exit ($?+=2); # exit mit exit status gesetzt

$av_std_DEBUG && say "debug \$av_loc_TO: $av_loc_TO";


$av_loc_CC =~s/ //u; # leerzeichen eleminieren
push(@av_loc_CC,split(/,/,join(',',$av_loc_CC))); # hier werden die einzelnen einträge in ein array überführt; trennzeichen=,
$av_std_DEBUG && say "debug \@av_loc_CC: @av_loc_CC";
if ($#av_loc_CC >= 1) # wenn 1 oder mehr elemente im array vorhanden sind muss das array in einen komma-getrennten string überführt werden
 
    $av_std_DEBUG && say "debug \@av_loc_CC: @av_loc_CC";
    $av_std_DEBUG && print "$_"."\n" foreach (@av_loc_CC);
    $av_loc_CC=''; # string löschen
#   shift(@av_loc_CC);
    foreach (@av_loc_CC)
    
        $av_loc_CC=$_.",".$av_loc_CC; #elemente des array mit komma getrennt zusammenführen - vorsicht - zum schluss ist 1 komma zuviel
    
    $av_loc_CC=substr($av_loc_CC,0,length($av_loc_CC)-1); # das letzte komma entfernen

else

    $av_loc_CC=join(' ', @av_loc_CC);

$av_std_DEBUG && say "debug \$av_loc_CC: $av_loc_CC";


#@av_loc_BCC=('dummy@av.loc');
$av_loc_BCC =~s/ //u; # leerzeichen eleminieren
push(@av_loc_BCC, split(/,/,join(',',$av_loc_BCC))); # hier werden die einzelnen einträge in ein array überführt; trennzeichen=,
$av_std_DEBUG && say "debug \@av_loc_BCC: @av_loc_BCC";
if ($#av_loc_BCC >= 1) # wenn 1 oder mehr elemente im array vorhanden sind muss das array in einen komma-getrennten string überführt werden
 
    $av_std_DEBUG && say "debug \@av_loc_BCC: @av_loc_BCC";
    $av_std_DEBUG && print "$_"."\n" foreach (@av_loc_BCC);
    $av_loc_BCC=''; # string löschen
#   shift(@av_loc_BCC);
    foreach (@av_loc_BCC)
    
        $av_loc_BCC=$_.",".$av_loc_BCC; #elemente des array mit komma getrennt zusammenführen - vorsicht - zum schluss ist 1 komma zuviel
    
    $av_loc_BCC=substr($av_loc_BCC,0,length($av_loc_BCC)-1); # das letzte komma entfernen

else

    $av_loc_BCC=join(' ', @av_loc_BCC);

$av_std_DEBUG && say "debug \$av_loc_BCC: $av_loc_BCC";


#@av_loc_FATT=('dummy.txt');
$av_loc_FATT =~s/ //u; # leerzeichen eleminieren
push(@av_loc_FATT, split(/,/,join(',',$av_loc_FATT))); # hier werden die einzelnen einträge in ein array überführt; trennzeichen=,
$av_std_DEBUG && say "debug \@av_loc_FATT: @av_loc_FATT";
if ($#av_loc_FATT >= 1) # wenn 1 oder mehr elemente im array vorhanden sind muss das array in einen komma-getrennten string überführt werden
 
    $av_std_DEBUG && say "debug \@av_loc_FATT: @av_loc_FATT";
    $av_std_DEBUG && print "$_"."\n" foreach (@av_loc_FATT);
    $av_loc_FATT=''; # string löschen
#   shift(@av_loc_FATT);
    foreach (@av_loc_FATT)
    
        $av_loc_FATT=$_.",".$av_loc_FATT; #elemente des array mit komma getrennt zusammenführen - vorsicht - zum schluss ist 1 komma zuviel
    
    $av_loc_FATT=substr($av_loc_FATT,0,length($av_loc_FATT)-1); # das letzte komma entfernen

else

    $av_loc_FATT=join(' ', @av_loc_FATT);

$av_std_DEBUG && say "debug \$av_loc_FATT: $av_loc_FATT";

@av_loc_FATT=($av_loc_FATT);
$av_std_DEBUG && say "debug \@av_loc_FATT: @av_loc_FATT";
foreach $av_tmp_STRING (@av_loc_FATT)

  if ( !-f "$av_tmp_STRING" )
  
    say "$av_tmp_STRING existiert nicht";
    exit ($?+=4);
  


$Mail::Sender::NO_X_MAILER=1; # wichtig der unterdrückt eine meldung im header wo auf das skript rückschlüsse gezogen werden kann.

$av_loc_FROMN = Encode::encode("MIME-Q", Encode::decode('UTF-8', $av_loc_FROMN));
$av_std_DEBUG && say "debug \$av_loc_FROMN: $av_loc_FROMN";
$av_loc_SUBJECT = Encode::encode("MIME-Q", Encode::decode('utf8', $av_loc_SUBJECT));
$av_std_DEBUG && say "debug \$av_loc_SUBJECT: $av_loc_SUBJECT";

$av_std_DEBUG && say "debug \$av_loc_TO: $av_loc_TO";
$av_std_DEBUG && say "debug \$av_loc_CC: $av_loc_CC";
$av_std_DEBUG && say "debug \$av_loc_BCC: $av_loc_BCC";
$av_std_DEBUG && say "debug \$av_loc_FROMN: $av_loc_FROMN";
$av_std_DEBUG && say "debug \$av_loc_FROME: $av_loc_FROME";
$av_std_DEBUG && say "debug \$av_loc_SUBJECT: $av_loc_SUBJECT";


ref ($av_tmp_MAIL = new Mail::Sender 
 
    from => $av_loc_FROMN.'<'.$av_loc_FROME.'>',
    replyto => $av_loc_FROME,
    to => $av_loc_TO,
    cc => $av_loc_CC,
    bcc => $av_loc_BCC,
  smtp => 'smtp.av.loc',

) or $av_std_DEBUG && say "debug Return code $av_tmp_MAIL" and exit (1);
$av_std_DEBUG && $Mail::Sender::Error && say "\$Mail::Sender::Error: $Mail::Sender::Error" && exit (1);


$av_tmp_MAIL->OpenMultipart (
  
    subject => $av_loc_SUBJECT,
    encoding => "Quoted-printable",
    multipart => 'Mixed',
    charset => 'UTF-8',
  
);
$av_std_DEBUG && $Mail::Sender::Error && say "\$Mail::Sender::Error: $Mail::Sender::Error" && exit (1);


open(BODY, '<', "$av_loc_FBODY") || # zum Lesen geöffnet
  say "debug: Cannot open file $av_loc_FBODY for reading! error: $!" && exit (1);

$av_tmp_STRING='';
while(my $eingabe=<BODY>)
  chomp($eingabe);
  $av_tmp_STRING = $av_tmp_STRING.Encode::decode("UTF-8", $eingabe)."\r\n";

$av_std_DEBUG && say "$av_tmp_STRING";

close(BODY); 
$av_std_DEBUG && say "debug \$ERRNO: $!";

$av_tmp_MAIL->Body (
  
    charset => 'UTF-8',
    encoding => 'Quoted-printable',
    ctype => 'text/plain',
    msg => $av_tmp_STRING,
  
);
$av_std_DEBUG && $Mail::Sender::Error && say "\$Mail::Sender::Error: $Mail::Sender::Error" && exit (1);
$av_std_DEBUG && say "debug \$ERRNO: $!";


$av_tmp_MAIL->Attach(

    description => 'Grundwasser Statistikdaten',
  file => @av_loc_FATT,

);
$av_std_DEBUG && $Mail::Sender::Error && say "\$Mail::Sender::Error: $Mail::Sender::Error" && exit (1);
$av_std_DEBUG && say "debug \$ERRNO: $!";

$av_tmp_MAIL->Close;
$av_std_DEBUG && $Mail::Sender::Error && say "\$Mail::Sender::Error: $Mail::Sender::Error" && exit (1);
$av_std_DEBUG && say "debug \$ERRNO: $!";

#  ______           _   _____                  
# |  ____|         | | |  __ \                 
# | |__   _ __   __| | | |__) | __ ___   ___   
# |  __| | '_ \ / _` | |  ___/ '__/ _ \ / __|  
# | |____| | | | (_| | | |   | | | (_) | (__ _ 
# |______|_| |_|\__,_| |_|   |_|  \___/ \___(_)
#                                              
#                                              
### end procedure
&av_logit("beendet");
exit (0);

【问题讨论】:

好像是编码问题!!! 见Encode::MIME::Header 或Email::MIME::RFC2047。 “变异”是一个非常奇怪的术语。如果你使用“accented”,你会在谷歌上获得更好的运气;甚至德语的“元音变音”在英语讨论中也被广泛理解。 【参考方案1】:

查看适合您的解决方案,您的输入变量似乎是编码的 UTF-8 字符串。这就是为什么你必须先解码它们。这本身可能是一个问题,但如果不了解其余代码,就无法判断。

要将编码为 UTF-8 的字符串转换为 MIME 标头编码,from_to function 比您的解决方案简单一些:

# Re-encodes $av_loc_FROMN in place.
Encode::from_to($av_loc_FROMN, "UTF-8", "MIME-Header");

正如@Andrzej 所述,您应该考虑 MIME-Q 编码。使用 MIME-Q,您编码的电子邮件标头在很大程度上保持人类可读。无论您使用“MIME-Header”(实际上是“MIME-B”)还是“MIME-Q”,这确实不应该有任何区别,所以我很困惑为什么你的尝试

$av_loc_FROMN = Encode::encode("MIME-Q", Encode::decode_utf8($av_loc_FROMN)); # ganz seltsam mit der leerstelle

没用。不过,旧版本的Encode 发行版存在许多关于 MIME 标头编码的错误。也许你遇到了其中之一。

如果您真的对代码的正确性感兴趣,我也不建议将 Encode::MIME::Header 用于包含 RFC 2822“邮箱”和“短语”的邮件标头,例如 From、To、Cc、Reply-To、等等。这是因为这个模块不涉及&lt;"@ 之类的字符,所有这些字符在这种情况下都可能具有特殊含义,应该被引用。通常,Encode::MIME::Header 仅对主题标题或仅包含字母数字字符的显示名称是安全的。对于邮箱的稳健处理,我推荐Email::MIME::RFC2047。 (披露:我是这个发行版的作者。)

【讨论】:

带有 MIME-Q 的版本可以正常工作,但效果很好。输入字符串是“Grundwasserfrühwarnsystem Forstinning”,结果是“Grundwasserfrühwarns”“stem Forstinning” 你看 - 有点好奇。所以我驳回了它。 我同时测试了几个模块。我会试试你推荐的那个。字符集和代码很难,而且我猜,只有专家才能透明。我根本不是一个人!【参考方案2】:

我的收获!

这是有效的结果 - 不要问我为什么!

$av_loc_FROMN = Encode::encode("MIME-Header", Encode::decode_utf8($av_loc_FROMN));

问候

卡尔-亨氏

【讨论】:

您使用哪种语言环境? (请参阅 LANG 环境变量)它是基于 UTF-8 的吗?)您在脚本中使用 use utf8; 吗? 顺便说一句,在“主要是 ascii”语言(如德语)中,强制 MIME-Q 编码是有意义的 - 它以原始格式留下“大部分可读”的标题。 @Andrzej:这是我的服务器运行的环境:locale LANG=de_DE.UTF-8 LANGUAGE=de:en LC_CTYPE=de_DE.UTF-8 LC_NUMERIC="de_DE.UTF-8" LC_TIME ="de_DE.UTF-8" LC_COLLATE=de_DE.UTF-8 LC_MONETARY="de_DE.UTF-8" LC_MESSAGES=de_DE.UTF-8 LC_PAPER="de_DE.UTF-8" LC_NAME="de_DE.UTF-8" LC_ADDRESS ="de_DE.UTF-8" LC_TELEPHONE="de_DE.UTF-8" LC_MEASUREMENT="de_DE.UTF-8" LC_IDENTIFICATION="de_DE.UTF-8" LC_ALL=

以上是关于如何发送带有变异元音的 Perl Mail::Sender? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

Javascript 正则表达式替换必须保留德语变异元音

如何将输入输出为每个辅音之间带有元音的字谜?

如何使用 mod_perl 发送自定义 http 状态码

Perl - 使用带有身份验证的 MIME::Lite 发送电子邮件时遇到问题

使用 perl 发送带有文件附件的多部分文本/html 替代消息,

如何使用 Perl Email::Mime 内联图像?