这个简单的代码段显示了我在Perl中使用JSON :: XS编码的问题:
#!/usr/bin/perl
use strict;
use warnings;
use JSON::XS;
use utf8;
binmode STDOUT, ":encoding(utf8)";
my (%data);
$data{code} = "Gewürztraminer";
print "data{code} = " . $data{code} . "\n";
my $json_text = encode_json \%data;
print $json_text . "\n";
Run Code Online (Sandbox Code Playgroud)
产生的输出是:
johnnyb@boogie:~/Projects/repos > ./jsontest.pl
data{code} = Gewürztraminer
{"code":"Gewürztraminer"}
Run Code Online (Sandbox Code Playgroud)
现在,如果我注释掉上面的binmode行,我得到:
johnnyb@boogie:~/Projects/repos > ./jsontest.pl
data{code} = Gew?rztraminer
{"code":"Gewürztraminer"}
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?请注意,我正在尝试在不能使用binmode的perl CGI脚本中修复此行为,但我总是在JSON流中返回上面返回的"¼"字符.我该如何调试?我错过了什么?
ike*_*ami 11
encode_json(缩写JSON::XS->new->utf8->encode)使用UTF-8 进行编码,然后通过将其打印到已添加编码层的STDOUT进行重新编码.实际上,你正在做encode_utf8(encode_utf8($uncoded_json)).
use open ':std', ':encoding(utf8)'; # Defaults
binmode STDOUT; # Override defaults
print encode_json(\%data);
Run Code Online (Sandbox Code Playgroud)
use open ':std', ':encoding(utf8)'; # Defaults
print JSON::XS->new->encode(\%data); # Or to_json from JSON.pm
Run Code Online (Sandbox Code Playgroud)
通过\u对非ASCII 使用转义,以下内容适用于STDOUT上的任何编码:
print JSON::XS->new->ascii->encode(\%data);
Run Code Online (Sandbox Code Playgroud)
在评论中,你提到它实际上是一个CGI脚本.
#!/usr/bin/perl
use strict;
use warnings;
use utf8; # Encoding of source code.
use open ':encoding(UTF-8)'; # Default encoding of file handles.
BEGIN {
binmode STDIN; # Usually does nothing on non-Windows.
binmode STDOUT; # Usually does nothing on non-Windows.
binmode STDERR, ':encoding(UTF-8)'; # For text sent to the log file.
}
use CGI qw( -utf8 );
use JSON::XS qw( );
{
my $cgi = CGI->new();
my $data = { code => "Gewürztraminer" };
print $cgi->header('application/json');
print encode_json($data);
}
Run Code Online (Sandbox Code Playgroud)