Search code examples
javascriptjsonperlutf-8mojolicious

Decode JSON string in Mojolicious that was encoded with JSON.stringify


I am trying to send javascript variable as JSON string to Mojolicious and I am having problems with decoding it on perl side. My page uses utf-8 encoding.

The json string (value of $self->param('routes_jsonstr')) seems to have correct value but Mojo::JSON can't decode it. The code is working well when there are no utf-8 characters. What am I doing wrong?

Javascript code:

        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 code:

sub on_route_change {
    my $self = shift;

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

Server output

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;

Last line above shows that decoding of json string didn't work. When there are no utf-8 characters to decode on perl side everything works fine and $routes contain expected data.


Solution

  • Mojolicious style solution can be found here: http://showmetheco.de/articles/2010/10/how-to-avoid-unicode-pitfalls-in-mojolicious.html

    In Javascript I only changed $.get() to $.post(). Updated and working Perl code now looks like this:

    use Mojo::ByteStream 'b';
    sub on_route_change {
        my $self = shift;    
        my $routes=j( b( $self->param('routes_jsonstr') )->encode('UTF-8') );
    }
    

    Tested with many different utf8 strings.