尝试在FastCGI下运行旧的CGI脚本。没有额外参数的打印可以提供正确的输出:print $q->div( $q->param("text") )
但是当使用CGI方法print $q->div( {-id=>"id"}, $q->param("text") )
的额外参数哈希打印出来时,它会破坏UTF-8形成的数据('õäöüžš' - >'ÃμÃÃÃÃÃÃÃÃÃüüžŻ)
仅在CGI参数中发生,在脚本定义的变量中工作正常(例3和4)。在普通的CGI(“-utf8”-flag)下,一切都很完美。
FastCGI转向的示例脚本,称为test.fcgi?text=õäöüžš
应该给出四个相等的块:
#!/usr/bin/perl -w --
use strict;
use CGI::Fast qw(:all);
use locale;
use utf8;
BEGIN {
binmode(STDIN); # Form data
binmode(STDOUT, ':encoding(UTF-8)'); # HTML
binmode(STDERR, ':encoding(UTF-8)'); # Error messages
}
my ($q) = ();
my $test = "õäöüžš";
while ($q = new CGI::Fast) {
print $q->header(-type=>"text/html", -charset=>"utf-8"),
$q->start_html(-encoding=>"utf-8");
print "1: ",
$q->div( $q->param('text') ),
"<br />",
"2: ",
$q->div( {-id=>"id"}, $q->param('text') ),
"<br />",
"3: ",
$q->div( $test ),
"<br />",
"4: ",
$q->div( {-id=>"id"}, $test ),
$q->end_html();
}
第一块很好,第二块破碎,第3块和第4块也很好:
普通的CGI示例,因为它给出了所有4种正确的方式:
#!/usr/bin/perl -w --
use strict;
use CGI qw(:all -utf8);
use locale;
use utf8;
BEGIN {
binmode(STDIN); # Form data
binmode(STDOUT, ':encoding(UTF-8)'); # HTML
binmode(STDERR, ':encoding(UTF-8)'); # Error messages
}
my ($q) = ();
my $test = "õäöüžš";
$q = new CGI;
print $q->header(-type=>"text/html", -charset=>"utf-8"),
$q->start_html(-encoding=>"utf-8");
print "1: ",
$q->div( $q->param('text') ),
"<br />",
"2: ",
$q->div( {-id=>"id"}, $q->param('text') ),
"<br />",
"3: ",
$q->div( $test ),
"<br />",
"4: ",
$q->div( {-id=>"id"}, $test ),
$q->end_html();
在我看来,使用FastCGI表单数据没有utf8-flag,我不明白,如何正确强制它?在CGI.pm下,我声明为:
use CGI qw(:all -utf8);
但是FastCGI怎么样?
答案 0 :(得分:5)
1)CGI::Fast是CGI.pm的子类,因此您可以指定相同的导入参数。
use CGI::Fast (-utf8);
2)FCGI流使用旧的流API TIEHANDLE实现。使用binmode()应用PerlIO图层无效。正确的解决方案是在输出数据之前对其进行编码,但如果这不是一个选项,我可以提供这个热补丁:
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use CGI::Fast (-utf8);
use FCGI ();
use Encode ();
my $enc = Encode::find_encoding('UTF-8');
my $org = \&FCGI::Stream::PRINT;
no warnings 'redefine';
local *FCGI::Stream::PRINT = sub {
my @OUTPUT = @_;
for (my $i = 1; $i < @_; $i++) {
$OUTPUT[$i] = $enc->encode($_[$i], Encode::FB_CROAK|Encode::LEAVE_SRC);
}
@_ = @OUTPUT;
goto $org;
};
my $literal = "õäöüžš";
while (my $q = CGI::Fast->new) {
print $q->header(-type => "text/html", -charset => "UTF-8"),
$q->start_html(-encoding => "UTF-8"),
$q->p("Text 1:" . $literal),
$q->p("Text 2:" . $q->param('text')),
$q->end_html;
}
答案 1 :(得分:1)
在Git 2.27(2020年第二季度)中,Gitweb应该解决该问题。
请参见commit 2ecfcde的Julien Moutinho (ju1m
)(2020年3月29日)。
(由Junio C Hamano -- gitster
--在commit 7a8bb6d中合并,2020年4月22日)
gitweb
:使用CGI :: Fast时修复UTF-8编码签名人:朱利安·穆蒂尼奥
FCGI流是使用较旧的流API:
TIEHANDLE
来实现的,因此,使用PerlIO
来应用binmode()
层对其没有影响。此补丁中的解决方案是重新定义
FCGI::Stream::PRINT
函数以将UTF-8用作输出编码,但必须git_blob_plain()
和git_snapshot()
以原始二进制模式输出。此问题和解决方案以前是在2012年报告的:
答案 2 :(得分:-2)
我愿意:
use strict;
use CGI;
CGI->compile();
use CGI::Fast;
use utf8;
while (new CGI::Fast) {
$CGI::PARAM_UTF8=1;# may be this????
my $q =CGI->new;
#rest of the code should work
}