在Mojolicious中解码使用JSON.stringify编码的JSON字符串

3

我正试图将Javascript变量作为JSON字符串发送到Mojolicious,并且在Perl方面解码时遇到了问题。我的页面使用utf-8编码。

JSON字符串($self->param('routes_jsonstr')的值)似乎有正确的值,但是Mojo::JSON无法解码它。当没有utf-8字符时,代码工作得很好。我做错了什么?

Javascript代码:

        var routes = [ {
            addr1: 'Škofja Loka', // string with utf-8 character
            addr2: 'Kranj'
        }];
        var routes_jsonstr = JSON.stringify(routes);
        $.get(url.on_route_change,
            {
                routes_jsonstr: routes_jsonstr
            }
        );

Perl 代码:

sub on_route_change {
    my $self = shift;

    my $routes=j( $self->param('routes_jsonstr') );
    warn $self->param('routes_jsonstr');
    warn Dumper $routes;
}

服务器输出

Wide character in warn at /opt/mojo/routes/script/../lib/Routes/Homepage.pm line 76. 
[{"addr1":"Škofja Loka","addr2":"Kranj"}] at /opt/mojo/routes/script/../lib/Routes/Homepage.pm line 76. 
$VAR1 = undef;

上面的最后一行显示json字符串的解码没有成功。当perl端没有需要解码的utf-8字符时,一切都正常工作,$routes包含预期的数据。


你需要在Mojo::JSON获取其参数值的地方应用:utf8流处理,但从我在CPAN上看到的Mojo::JSON文档中,它似乎已经这样做了。如果可以的话,请尝试安装和使用来自CPAN的JSON模块;我使用它来解码UTF8编码的JSON数据取得了良好的结果。 - Aaron Miller
1
$routes=JSON->new->utf8(0)->decode( $self->param('routes_jsonstr') ); - 410503
你能用Mojo::JSON做到这一点吗,还是只能用JSON.pm? - Aaron Miller
1
抱歉之前的评论有误:我已经使用JSON.pm使其正常工作,并禁用了utf8。这似乎可以解决问题:$routes=JSON->new->utf8(0)->decode( $self->param('routes_jsonstr') );。启用utf8(1)会出现错误Wide character in subroutine entry at /opt/mojo...。我还在JavaScript中将$.get()替换为$.post(),但我认为这没有影响。 - 410503
哦,太棒了!你介意我把这个评论转换成答案吗? - Aaron Miller
是的,请将其转换。感谢您的帮助! - 410503
3个回答

3
这里可以找到Mojolicious风格的解决方案: http://showmetheco.de/articles/2010/10/how-to-avoid-unicode-pitfalls-in-mojolicious.html 在JavaScript中,我只将$.get()更改为$.post()。 现在更新并正常工作的Perl代码看起来像这样:
use Mojo::ByteStream 'b';
sub on_route_change {
    my $self = shift;    
    my $routes=j( b( $self->param('routes_jsonstr') )->encode('UTF-8') );
}

使用多种不同的UTF8字符串进行测试。


1

当你打印输出时,会出现宽字符警告。这不是由于你解码unicode的方式,而是由于STDOUT编码方式。尝试使用CPAN提供的use utf8::all,它将设置所有IO句柄为utf8。避免解码可能并不能解决问题,反而会让问题变得更糟。唯一的原因是你的终端正在为你修复问题。


1

谢谢。当使用您提供的链接中建议的自定义JSON_stringify函数时,我可以在Perl端启用utf8解码:$routes=JSON->new->utf8(1)->decode( $self->param('routes_jsonstr') ); - 410503

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接