2015-11-06 29 views
1

我面临use JSON::XS qw(encode_json);中encode_json函数的问题。我们有一个基于Web的项目,以Perl,JavaScript,jQuery和MySQL作为后端。使用encode_json后,重音字符得到双重编码

在应用程序的特定屏幕中,用户的名称会失真。

问题是用户名是西班牙文,并有重音字符。 我们正在保存数据库的表是旧表,并具有字符集latin 1,但是当我读取数据时,我使用了转换并将其转换并编码为UTF-8格式。

select CONVERT(CAST(CONVERT(u.last_name USING latin1) AS BINARY) USING utf8) AS last_name from user where user_id = 'XXX' 

在我存储数据库结果的结构中,数据显示正常。

{ last_name => Cvas García} 

这种结构被传递给这使得页面

$data_json = encode_json($data) 

当我打印$data_json,重音字符再次扭曲javascript函数。

"user_permissions":[{"last_name":"Cvas García"}]}, 

任何人都可以帮我解决这个问题,无论是在Mysql或perl或JavaScript代码?

回答

-1

试试这个

use JSON; 
use utf8; 
use Data::Printer; 
utf8::encode($data) unless (utf8::is_utf8($data)); 
p encode_json($data); 
+0

如果您使用'is_utf8',则会出错。 – ikegami

2

表的字符集是无关紧要的。 MySQL会自动将表的编码转换为连接的编码。然后,您必须在Perl端解码它,或者明确地将mysql_enable_utf8 => 1传递给connect。我推荐后者。

use utf8;        # Source code encoded using UTF-8. 
use open ':std', ':encoding(UTF-8)'; # Terminal expects/provides UTF-8. 

use DBI  qw(); 
use JSON::XS qw(encode_json); 

my $user_id = "..."; 

my $dsn = "..."; 
my $user = "..."; 
my $password = "..."; 

my $dbh = DBI->connect("dbi:mysql:".$dsn, $user, $password, { 
    PrintError => 0, 
    RaiseError => 1, 
    mysql_enable_utf8 => 1, # Switch to UTF-8 for communication and decode. 
}); 

my $name = $dbh->selectrow_array(" 
    SELECT `last_name` 
    FROM `user` 
    WHERE `user_id` = ? 
", undef, $user_id); 

# Encoding being performed by "use open". 
print(sprintf("%vX", $name), "\n");  # 47.61.72.63.ED.61 
print($name, "\n");      # García 

# Encoding being performed by "use open". 
my $json = JSON::XS->new->encode([$name]); 
print(sprintf("%vX", $json), "\n");  # 5B.22.47.61.72.63.ED.61.22.5D 
print($json, "\n");      # ["García"] 

binmode(STDOUT); # Override "use open". 
my $json_utf8 = JSON::XS->new->utf8->encode([$name]); # aka encode_json([$name]) 
print(sprintf("%vX", $json_utf8), "\n"); # 5B.22.47.61.72.63.C3.AD.61.22.5D 
print($json_utf8, "\n");     # ["García"] 
+0

感谢您的建议。我没有得到与您的代码中提到的相同的输出。这是我得到的输出。 '43.75.65.76.61.73.20.47.61.72.63.ED.61 奎瓦斯GarcÃa 5B.22.43.75.65.76.61.73.20.47.61.72.63.ED.61.22.5D [ “奎瓦斯GarcÃa”] 5B.22.43 .75.65.76.61.73.20.47.61.72.63.C3.AD.61.22.5D [“CuevasGarcÃa”]'...保存在用户表中的初始数据本身是否已损坏? –

+0

十六进制显示字符串是正确的,所以你根本没有为你的终端指定正确的编码。 – ikegami

+0

'ED'是latin1编码; 'C3 AD'是utf8编码。 –