【问题标题】:Perl and HTML: UTF8 does not work in formsPerl 和 HTML:UTF8 在表单中不起作用
【发布时间】:2014-09-03 01:13:27
【问题描述】:

我尝试将我的 Perl / HTML 文件更改为 UTF-8 格式。不幸的是,我的表格有问题。我创建了一个小测试脚本来说明这个问题。它所做的只是重新加载自身,以便再次显示输入的文本。它适用于 ASCII 字符。一旦我输入德语“元音变音”(ÄÖÜ),字符就会被扭曲。它也不能处理俄语字符(ЭЯЮ)。这是脚本:

#!/usr/bin/perl

use utf8;
use Encode;
use open ':std', ':encoding(UTF-8)';

# Safe query-string in hash:
$querystring = $ENV{ 'QUERY_STRING' };
read(STDIN, $poststring, $ENV{CONTENT_LENGTH});
if (($querystring ne "") && ($poststring ne "")) { $querystring .= "&$poststring"; } 
    else { $querystring .= $poststring; }

$querystring =~ s/&/=/gi;
%query = split( /=/, $querystring );
foreach $key ( keys( %query ) ) {
    $query{$key} =~ tr/+/ /;
    $query{$key} =~ s/%([\da-f][\da-f])/chr( hex($1) )/egi;
    $uquer{$key} = decode_utf8( $query{$key} );
}

print "Content-Type: text/html; charset=\"UTF-8\"\n\n";
print <<END;
    <HTML>
        <HEAD>
            <META HTTP-EQUIV="Content-Type" content="text/html; charset=utf-8">
        </HEAD>
        <BODY>
            <FORM NAME="frmeing" METHOD="POST" ACTION="test0.cgi">
                <INPUT NAME="df_kurs" TYPE="TEXT" VALUE="$uquer{'df_kurs'}">
                <INPUT TYPE="SUBMIT">
            </FORM>
        </BODY>
    </HTML>
END

您也可以测试此脚本。它在这个地址在线: http://project-website.org/test/test0.cgi 有谁知道可能是什么问题?提前感谢您的帮助!

【问题讨论】:

    标签: html perl utf-8 character-encoding


    【解决方案1】:

    这是由于您的 decode_utf8 版本中存在错误。

    $ perl -Mutf8 -MEncode -E'
       $u = $d = encode_utf8("é");
       utf8::upgrade($u);   # Changes how the string is stored internally
       say $u eq $d ?1:0;
       say decode_utf8($d) eq decode_utf8($u) ?1:0;
    '
    1
    0
    

    如您所见,$u$d 是相等的,但您的 decode_utf8 版本对它们的解码方式不同。具体来说,它返回 $u 不变。

    此问题已在较新版本的 Encode 中得到修复。 (我认为是 2.53。)

    解决问题的更简单方法是修复您自己的错误。使用use open,您告诉您的程序从 UTF-8 解码 STDIN,然后再从 UTF-8 取消转义 url 编码和解码。

    修复:

    #!/usr/bin/perl
    
    use utf8;                      # Source code is encoded using UTF-8.
    use open ':encoding(UTF-8)';   # Set default encoding for file handles.
    BEGIN { binmode(STDOUT, ':encoding(UTF-8)'); }  # HTML
    BEGIN { binmode(STDERR, ':encoding(UTF-8)'); }  # Error log
    
    use Encode;
    
    # Safe query-string in hash:
    $querystring = $ENV{ 'QUERY_STRING' };
    read(STDIN, my $poststring, $ENV{CONTENT_LENGTH});
    if (($querystring ne "") && ($poststring ne "")) { $querystring .= "&$poststring"; } 
        else { $querystring .= $poststring; }
    
    $querystring =~ s/&/=/gi;
    %query = split( /=/, $querystring );
    foreach $key ( keys( %query ) ) {
        $query{$key} =~ tr/+/ /;
        $query{$key} =~ s/%([\da-f][\da-f])/chr( hex($1) )/egi;
        $uquer{$key} = decode_utf8( $query{$key} );
    }
    
    print "Content-Type: text/html; charset=\"UTF-8\"\n\n";
    print <<END;
        <HTML>
            <HEAD>
                <META HTTP-EQUIV="Content-Type" content="text/html; charset=utf-8">
            </HEAD>
            <BODY>
                <FORM NAME="frmeing" METHOD="POST">
                    <INPUT NAME="df_kurs" TYPE="TEXT" VALUE="$uquer{'df_kurs'}">
                    <INPUT TYPE="SUBMIT">
                </FORM>
            </BODY>
        </HTML>
    END
    

    但你真的应该使用 CGI.pm。

    #!/usr/bin/perl
    
    use strict;    # Always!
    use warnings;  # Always!
    
    use utf8;                      # Source code is encoded using UTF-8.
    use open ':encoding(UTF-8)';   # Set default encoding for file handles.
    BEGIN { binmode(STDOUT, ':encoding(UTF-8)'); }  # HTML
    BEGIN { binmode(STDERR, ':encoding(UTF-8)'); }  # Error log
    
    use CGI qw( -utf8 );
    use Encode;
    
    my $cgi = CGI->new();
    my %uquer = $cgi->Vars();
    
    print $cgi->header('text/html; charset=UTF-8');
    print <<END;
        <HTML>
            <HEAD>
                <META HTTP-EQUIV="Content-Type" content="text/html; charset=utf-8">
            </HEAD>
            <BODY>
                <FORM NAME="frmeing" METHOD="POST">
                    <INPUT NAME="df_kurs" TYPE="TEXT" VALUE="$uquer{'df_kurs'}">
                    <INPUT TYPE="SUBMIT">
                </FORM>
            </BODY>
        </HTML>
    END
    

    【讨论】:

    • 很好的答案。谢谢
    猜你喜欢
    • 2015-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-03
    • 2016-06-12
    • 1970-01-01
    • 2012-07-11
    • 1970-01-01
    相关资源
    最近更新 更多