我在更新/升级某些遗留代码时遇到了一种奇怪的情况。
我有一个包含HTML的变量。在我输出它之前,它必须填充大量数据。从本质上讲,我有以下内容:
for my $line (@lines) {
$output = loadstuff($line, $output);
}
在loadstuff()
内,有以下
sub loadstuff {
my ($line, $output) = @_;
# here the process is simplified for better understanding.
my $stuff = getOtherStuff($line);
my $result = $output.$stuff;
return $result;
}
此功能构建一个由不同区域组成的页面。所有区域都是独立加载的,这就是为什么有一个for循环。
麻烦就在这里开始吧。当我从头开始加载页面时(单击链接,Perl执行并传递HTML),一切都正常加载。每当我通过AJAX加载第二页进行比较时,HTML就会破坏编码。
我将问题追溯到此行my $result = $output.$stuff
。在连接之前,$output
和$stuff
没问题。但之后,$result
中的编码混乱了。
是否有人知道为什么连接会混淆我的编码?虽然我们在讨论这个问题,但为什么只有在通过AJAX完成调用时才会发生?
Perl和AJAX调用都执行与构建页面完全相同的功能。因此,每当我为AJAX修复它时,它就会因新重新加载的页面而被破坏。它似乎只有在AJAX启动呼叫时才会发生。
这种特殊情况的唯一区别是页面的当前值与较旧的值进行比较(它是备份/恢复功能)。从这里开始,一切都是一样的。变量中的编码(据我所知)是可以的。我甚至只对从AJAX加载的值尝试了Encode函数,但无济于事。根据“凯特”,文件本身似乎是utf8。
除此之外,我有另一个具有相同行为的函数,它使用完全相同的函数,值和文件。从Perl / Apache启动调用时,编码正常。通过AJAX再次,它搞砸了。
我一直在检查AJAX请求(jQuery)并且找不到任何奇怪的东西。编码似乎也是utf8。
答案 0 :(得分:4)
Perl的每个标量值都有一个“utf8”标志,可以是“开”或“关”。标志的“On”状态告诉perl将值视为Unicode字符串。
如果你取一个带有utf8标志的字符串并将其与一个打开了utf8标志的字符串连接起来,perl会将第一个字符串转换为Unicode。这是问题的常见原因。
在连接之前,您需要将两个变量转换为Encode::encode()
的字节或转换为perl的内部格式{。}}。
答案 1 :(得分:2)
扩展上一个答案,这里有一些我发现有用的信息,当我开始搞乱Perl中的字符编码时。
这是perl中对Unicode的出色介绍:http://perldoc.perl.org/perluniintro.html。 “Perl的Unicode模型”部分与您所看到的问题特别相关。
在Perl中使用的一个好规则是将数据解码为Perl字符,并在其出路时将其编码为字节。您可以使用Encode::encode
和Encode::decode
明确执行此操作。如果您正在读取/写入文件句柄,则可以使用binmode
并设置图层来指定文件句柄的编码:perldoc -f binmode
您可以使用Encode::is_utf8
判断示例中的哪些字符串已被解码为Perl字符:
use Encode qw( is_utf8 );
print is_utf8($stuff) ? 'characters' : 'bytes';
答案 2 :(得分:0)
我的一位同事找到了这个问题的答案。它确实与AJAX启动呼叫的事实有关。
文件结构如下:
1个处理程序,由Apache访问
1个处理程序,由Apache访问但只包含AJAX响应程序。我们称之为AJAX-Handler
1个包,其中包含与整个软件相关的功能,他们访问我们自己的Framework中的其他包
在AJAX-Handler内部,我们打印结果
sub handler {
my $r = shift;
# processing output
$r->print($output);
return Apache2::Const::OK;
}
现在,当我将$r->print($output);
替换为print($output);
时,问题就会消失!我知道这不是在mod_perl中打印东西的推荐方法,但这似乎有效。
尽管如此,欢迎任何有关如何以正确方式做到这一点的想法。