首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Rails没有正确地从jQuery中解码JSON (数组变成了带有整数键的散列)

Rails没有正确地从jQuery中解码JSON (数组变成了带有整数键的散列)
EN

Stack Overflow用户
提问于 2011-06-20 20:03:46
回答 7查看 27.8K关注 0票数 91

每次我想向Rails发布一个带有jQuery的JSON对象数组时,都会遇到这个问题。如果我对数组进行字符串化,我可以看到jQuery正在正确地工作:

"shared_items"=>"[{\"entity_id\":\"253\",\"position\":1},{\"entity_id\":\"823\",\"position\":2}]"

但是如果我只是将它作为AJAX调用的数据发送给数组,我会得到:

"shared_items"=>{"0"=>{"entity_id"=>"253", "position"=>"1"}, "1"=>{"entity_id"=>"823", "position"=>"2"}}

然而,如果我只发送一个普通数组,它就可以工作:

"shared_items"=>["entity_253"]

为什么Rails要将数组更改为这种奇怪的散列?我想到的唯一原因是Rails不能正确理解内容,因为这里没有类型(有没有办法在jQuery调用中设置它?):

Processing by SharedListsController#create as 

谢谢!

更新:我将数据作为数组发送,而不是字符串,并且该数组是使用.push()函数动态创建的。尝试使用$.post$.ajax,结果相同。

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2012-07-28 10:11:42

如果有人偶然发现了这一点并想要更好的解决方案,您可以在.ajax调用中指定“JSON:'application/json'”选项,让Rails正确地解析contentType对象,而不会将其混淆为具有全字符串值的整数键哈希。

所以,总结一下,我的问题是:

$.ajax({
  type : "POST",
  url :  'http://localhost:3001/plugin/bulk_import/',
  dataType: 'json',
  data : {"shared_items": [{"entity_id":"253","position":1}, {"entity_id":"823","position":2}]}
});

导致Rails将内容解析为:

Parameters: {"shared_items"=>{"0"=>{"entity_id"=>"253", "position"=>"1"}, "1"=>{"entity_id"=>"823", "position"=>"2"}}}

鉴于此(注意:我们现在对javascript对象进行了字符串化并指定了一个内容类型,因此rails将知道如何解析我们的字符串):

$.ajax({
  type : "POST",
  url :  'http://localhost:3001/plugin/bulk_import/',
  dataType: 'json',
  contentType: 'application/json',
  data : JSON.stringify({"shared_items": [{"entity_id":"253","position":1}, {"entity_id":"823","position":2}]})
});

在Rails中生成一个很好的对象:

Parameters: {"shared_items"=>[{"entity_id"=>"253", "position"=>1}, {"entity_id"=>"823", "position"=>2}]}

这在Ruby 1.9.3上的Rails3中适用。

票数 169
EN

Stack Overflow用户

发布于 2011-08-11 06:20:31

这个问题有点老生常谈,但今天我自己也遇到了这个问题,下面是我想出的答案:我认为这是jQuery的错,但它只是顺其自然。然而,我确实有一个变通的办法。

给定以下jQuery ajax调用:

$.ajax({
   type : "POST",
   url :  'http://localhost:3001/plugin/bulk_import/',
   dataType: 'json',
   data : {"shared_items": [{"entity_id":"253","position":1},{"entity_id":"823","position":2}]}

});

jQuery将发布的值将如下所示(如果您查看您的Firebug-of-choice中的请求)将为您提供如下形式的数据:

shared_items%5B0%5D%5Bentity_id%5D:1
shared_items%5B0%5D%5Bposition%5D:1

如果你用CGI.unencode搜索,你会得到

shared_items[0][entity_id]:1
shared_items[0][position]:1

我相信这是因为jQuery认为JSON中的那些键是表单元素名称,它应该将它们视为您有一个名为"username“的字段。

所以它们进入你的Rails应用程序,Rails看到括号,并构造一个散列来保存字段名的最里面的键( jQuery“有帮助地”添加的"1“)。

无论如何,我通过如下方式构造我的ajax调用来绕过这个行为;

$.ajax({
   type : "POST",
   url :  'http://localhost:3001/plugin/bulk_import/',
   dataType: 'json',
   data : {"data": JSON.stringify({"shared_items": [{"entity_id":"253","position":1},{"entity_id":"823","position":2}])},
  }
});

这迫使jQuery认为这个JSON是您想要完全传递的值,而不是它必须接受的Javascript对象,并将所有键转换为表单字段名称。

然而,这意味着Rails方面的情况有所不同,因为您需要显式地解码params:data中的JSON。

但这也没关系:

ActiveSupport::JSON.decode( params[:data] )

TL;DR:所以,解决方案是:在你的jQuery.ajax()调用的数据参数中,显式地执行{"data": JSON.stringify(my_object) },而不是将JSON数组输入到jQuery (它会错误地猜测你想要用它做什么。

票数 13
EN

Stack Overflow用户

发布于 2014-08-25 10:22:34

我刚刚在Rails 4中遇到了这个问题。要明确回答您的问题(“为什么Rails要将数组更改为这种奇怪的散列?”),请参阅Rails guide on Action Controllers的4.1节

若要发送一组值,请将一对空的方括号"[]“附加到键名。

问题是,jQuery使用显式数组索引来格式化请求,而不是使用空方括号。因此,例如,它发送shared_items[0]=1&shared_items[1]=2而不是发送shared_items[]=1&shared_items[]=2。Rails查看数组索引并将其解释为散列键而不是数组索引,从而将请求转换为奇怪的Ruby散列:{ shared_items: { '0' => '1', '1' => '2' } }

如果您无法控制客户端,可以通过将散列转换为数组在服务器端修复此问题。下面是我是如何做到的:

shared_items = []
params[:shared_items].each { |k, v|
  shared_items << v
}
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6410810

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档