jQuery.ajax()
将复杂的JavaScript对象编码为查询字符串,如下所示:
?a[b][]=1&a[b][]=2&a[c]=3
我想将其解码为Perl数据结构,如下所示:
{ a=>{ b=>[1,2], c=>3 } }
PHP默认执行此操作。有没有办法在Perl CGI脚本中执行此操作?不一定使用CGI.pm;我可以安装我想要的任何库。
到目前为止,我只能解码一维数组,因为CGI模块的param()
函数可以返回一个数组。
答案 0 :(得分:4)
您是否考虑过以JSON格式提交数据?这只是一个替换
的问题data: data
与
data: JSON.stringify(data)
您甚至可以切换到POST
以避免URI编码,URI解码和查询大小限制(尽管POST语义与GET语义不同)。
method: "POST",
contentType: "application/json; charset=UTF-8",
data: JSON.stringify(data)
无论如何,以下应该可以解决问题:
use Data::Diver qw( DiveVal );
use List::Util qw( pairs ); # 1.29+
use URI qw( );
my $url = URI->new('?a[b][]=1&a[b][]=2&a[c]=3', 'http');
my %data;
PAIR: for ( pairs( $url->query_form() ) ) {
my ($k, $v) = @$_;
my ( @k, $push );
for (my $k_ = $k) { # Basically C<< my $_ = $k; >>
s/^(\w+)//
or warn("Can't handle key $k\n"), next PAIR;
push @k, $1;
push @k, $1 while s/^\[(\w+)\]//;
$push = s/^\[\]//;
$_ eq ""
or warn("Can't handle key $k\n"), next PAIR;
}
if ($push) {
push @{ DiveVal(\%data, @k) }, $v;
} else {
DiveVal(\%data, @k) = $v;
}
}
早于5.16的Perl版本需要一种解决方法。取代
use Data::Diver qw( DiveVal );
push @{ DiveVal(\%data, @k) }, $v;
与
use Data::Diver qw( DiveRef DiveVal );
push @{ ${ DiveRef(\%data, @k) } }, $v;
请注意,格式不明确 [1] 。例如,以下两个表达式产生相同的结果(a[0][x]=3
[2] ):
jQuery.param( { a: [ { x: 3 } ] } )
jQuery.param( { a: { "0": { x: 3 } } } )
我的代码将重现前者。数字键始终被视为数组索引。
答案 1 :(得分:1)
PHP解释像foo[]=123&foo[]=234&foo[]=345
这样的查询字符串与所有Perl Web框架不同。我曾经为Mojolicious构建了一个PHP插件,并且必须解决很多这些差异。您可以找到这些差异的摘要和一些工作代码(最多可用于2级哈希),将Perl参数转换为PHP风格的参数here。也许你可以根据你的用例调整它。