W3C*_*der -3 unicode perl utf-8
通过这个论坛,我了解到使用以下内容将CGI输入(从escape()d Ajax调用或普通HTML表单发送)转换为UTF-8 不是一个好主意:
read (STDIN, $_, $ENV{CONTENT_LENGTH});
s{%([a-fA-F0-9]{2})}{ pack ('C', hex ($1)) }eg;
utf8::decode $_;
Run Code Online (Sandbox Code Playgroud)
更安全的方式(例如,不允许伪造字符通过)是执行以下操作:
use Encode qw (decode);
read (STDIN, $_, $ENV{CONTENT_LENGTH});
s{%([a-fA-F0-9]{2})}{ pack ('C', hex ($1)) }eg;
decode ('UTF-8', $_, Encode::FB_CROAK);
Run Code Online (Sandbox Code Playgroud)
但是,我非常希望避免使用任何模块(包括XSLoader,Exporter以及它们带来的任何其他模块).该函数适用于大量mod_perl驱动的网站,我认为没有模块,性能和可维护性都会更好(特别是因为当前代码不使用任何模块).
我想一种方法是检查Encode模块并去除用于"decode('UTF-8',$ _,Encode :: FB_CROAK)"调用的函数和常量.我不熟悉Unicode和Perl模块来做到这一点.也许其他人有能力这样做或者知道一种类似的,安全的"原生"方式进行UTF-8转换?
更新:
我更喜欢保持非模块化的东西,因为那时唯一的黑盒子是Perl自己的编译器(当然除非你深入到模块库中).
有时您会看到大型模块被一些特定的代码行替换.例如,代替CGI.pm模块(人们也喜欢它),可以使用以下内容来解析AJAX帖子:
my %Input;
if ($ENV{CONTENT_LENGTH}) {
read (STDIN, $_, $ENV{CONTENT_LENGTH});
foreach (split (/&/)) {
tr/+/ /; s/%([a-fA-F0-9]{2})/pack("C", hex($1))/eg;
if (m{^(\w+)=\s*(.*?)\s*$}s) { $Input{$1} = $2; }
else { die ("bad input ($_)"); }
}
}
Run Code Online (Sandbox Code Playgroud)
以类似的方式,如果可以提取或复制Encode的UTF-8解码功能,那将会很棒.
不要预先优化.首先采用传统方式,然后进行配置文件和基准测试,以了解您需要优化的位置.人们通常会将所有时间都浪费在其他地方,所以开始蒙眼和被铐起来并没有给你任何好处.
不要害怕模块.mod_perl的目的是尽可能少地加载所有内容,因此启动时间和模块加载时间无关紧要.