折腾我好几个小时,靠,赶紧记下来!
JSON::XS的中文兼容问题
最近遇到一个编码的问题,图中第一行是正确的内容,第二行和第三行是JSON片段:
![json-xs-wrong.png](http://aaba.me/blog/blogimg/2010/01/json/json-xs-wrong.png)
因为数据来源有各种方向,有些经过转码处理,有些没有,使用JSON::XS生成JSON的时候,生成的中文内容有时候是乱码。后来终于发现了问题所在:
JSON::XS在编码处理utf-8的时候,传入的变量必须是perl内部表示为utf-8的标量,而不能是raw数据。可能和JSON::XS是C语言实现有关吧。
处理以后终于正常了:
![json-xs-correct.png](http://aaba.me/blog/blogimg/2010/01/json/json-xs-correct.png)
重现问题和解决问题的代码如下,文件编码:utf-8
#!/usr/bin/perl use JSON::XS; use Encode; use Data::Dumper; use strict; use warnings; my $content = "这是一段中文内容"; print "转码前的内部表示:\n"; print Dumper $content, "\n"; print "转码前的JSON:\n"; print JSON::XS->new->utf8->encode({ content => $content }), "\n";
# 对内容做一次转码就可以正常输出JSON了 $content = decode("utf-8", $content); print "转码后的内部表示:\n"; print Dumper $content, "\n"; print "转码后的JSON:\n"; print JSON::XS->new->utf8->encode({ content => $content }), "\n"; 输出结果如下: 转码前的内部表示: $VAR1 = '这是一段中文内容'; $VAR2 = ' '; 转码前的JSON: {"content":"这是一段ä¸æ–‡å†…容"} 转码后的内部表示: $VAR1 = "\x{8fd9}\x{662f}\x{4e00}\x{6bb5}\x{4e2d}\x{6587}\x{5185}\x{5bb9}"; $VAR2 = ' '; 转码后的JSON: {"content":"这是一段中文内容"}