【问题标题】:Decode JSON string in Mojolicious that was encoded with JSON.stringify在 Mojolicious 中解码使用 JSON.stringify 编码的 JSON 字符串
【发布时间】:2013-04-24 12:49:50
【问题描述】:

我正在尝试将 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 包含预期的数据。

【问题讨论】:

  • 您需要将 :utf8 流规则应用于 Mojo::JSON 从中获取其参数值的任何位置,但从我在 CPAN 上的 Mojo::JSON 文档中看到的内容来看,它应该显然已经在这样做了。如果可以,请尝试从 CPAN 安装和使用 JSON 模块;我使用它来解码 utf8 编码的 JSON 数据取得了很好的效果。
  • $routes=JSON->new->utf8(0)->decode( $self->param('routes_jsonstr') );
  • 你能用 Mojo::JSON 做到这一点,还是只用 JSON.pm?
  • 很抱歉我之前的评论失败了:我让它与 JSON.pm 一起工作并禁用了 utf8。这似乎有效:$routes=JSON->new->utf8(0)->decode( $self->param('routes_jsonstr') );。启用 utf8(1) 后,它会因错误 Wide character in subroutine entry at /opt/mojo... 而死。我还在 javascript 中用 $.post() 替换了 $.get() 但我认为这没有效果。
  • 太棒了!介意我将评论转换为答案吗?

标签: javascript json perl utf-8 mojolicious


【解决方案1】:

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 字符串进行测试。

【讨论】:

    【解决方案2】:

    通过逃避有问题的角色,您至少可以消除一些痛苦;见https://stackoverflow.com/a/4901205/17389

    【讨论】:

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

    打印时会出现宽字符警告。这不是因为你如何解码你的 unicode,而是你的 STDOUT 编码。尝试 CPAN 提供的use utf8::all,它将所有 IO 句柄设置为 utf8。避免解码可能并不能解决问题,反而会使问题变得更糟。它似乎工作的唯一原因是您的终端正在为您解决问题。

    【讨论】:

      猜你喜欢
      • 2021-06-11
      • 2016-05-31
      • 2018-11-05
      • 2013-06-15
      • 2017-06-14
      • 1970-01-01
      • 2010-11-09
      • 2016-01-02
      • 2013-03-19
      相关资源
      最近更新 更多