【问题标题】:How can I convert this hash into workable JSON?如何将此哈希转换为可用的 JSON?
【发布时间】:2014-04-07 11:26:05
【问题描述】:

IE10 正在返回参数,看起来像是对 JSON 的双重转换:

=> {"{\"statementId\":"=>
  {"\"b3dsecret9-bsecret741-23secreta806c\""=>
    {",\"Content-Type\":"=>
      {"\"application/json\""=>
        {",\"content\":"=>
          {"\"{\\\"context\\\":{\\\"registration\\\":\\\"27\\\",\\\"contextActivities\\\":{\\\"parent\\\":{\\\"id\\\":\\\"6LHIJumrnmV_course_id\\\"},\\\"grouping\\\":{\\\"id\\\":\\\"6LHIJumrnmV_course_id\\\"}}},\\\"actor\\\":213,\\\"verb\\\":\\\"attempted\\\",\\\"object\\\":{\\\"id\\\":\\\"6LHIJumrnmV_course_id\\\",\\\"definition\\\":{\\\"name\\\":{\\\"und\\\":\\\"\\\"},\\\"type\\\":\\\"Course\\\",\\\"description\\\":{\\\"und\\\":\\\"\\\"}}}}\""=>
            {",\"registration\":"=>
              {"\"27\""=>
                {",\"AWSAccessKeyId\":"=>
                  {"\"secretIAIVsecretPHsecretQ\""=>
                    {",\"Signature\":"=>
                      {"\"PJ /OW K5secretasyXsecret5A"=>
                        "\"],\"Expires\":[\"1396873090\"],\"Authorization\":[\"\"]}"}}}}}}}}}}},
 "method"=>"PUT",
 "controller"=>"quizzes",
 "action"=>"statements"}

IE Edge、Safari、Chrome 和 Firefox 像这样返回我的参数:

=> {"registration"=>["27"],
 "Content-Type"=>["application/json"],
 "Signature"=>["secretkqPJGPEsecret01ksecret"],
 "AWSAccessKeyId"=>["Asecret6secretPHsecretQ"],
 "statementId"=>["5919c4f4-b71c-40dd-81dc-ab63cfc824bd"],
 "Expires"=>["1396873699"],
 "Authorization"=>[""],
 "content"=>
  ["{\"object\":{\"definition\":{\"type\":\"Course\",\"name\":{\"und\":\"\"},\"description\":{\"und\":\"\"}},\"id\":\"6LHIJumrnmV_course_id\"},\"verb\":\"attempted\",\"context\":{\"registration\":\"27\",\"contextActivities\":{\"parent\":{\"id\":\"6LHIJumrnmV_course_id\"},\"grouping\":{\"id\":\"6LHIJumrnmV_course_id\"}}},\"actor\":213}"],
 "method"=>"PUT",
 "controller"=>"quizzes",
 "action"=>"statements",
 "quiz"=>{}

所以我的代码可以方便地解析这个:

content = params[:content] || params['content']
response = JSON.parse(content.first)

然后转眼!我有一个可行的内容。但是对于前面提到的第一个哈希,我不确定如何转换它。我是否应该考虑使用 match/gsub 技术来删除所有那些邪恶的正斜杠?有没有办法将它破译成看起来像我的后一个哈希的东西?

【问题讨论】:

  • 我认为你应该避免修复错误服务器端,而是修复它客户端,因为错误是客户端
  • IE 会生成它。我不确定我是否理解你的建议。无论如何,因为我正在使用黑盒 API(这意味着我无法触及它产生的内容).. 我只需要处理它呈现给我的任何废话。
  • 为了提供帮助,我们需要知道是什么导致 IE 出现这种行为。请描述触发该响应的情况并显示代码。是Javascript吗?
  • 我不确定是否有办法找到答案。我有一个黑盒 API(在 Flash 中),我在 iFrame 中加载。加载应用程序后,它会向我的服务器发送请求。如果我使用 IE10 或更少,它返回的参数就像我提到的示例一样。我无法调整或查看 API 的代码本身。

标签: ruby-on-rails ruby json internet-explorer hash


【解决方案1】:

从您的回答开始,我将使用escape_utils gem 解析key

require 'escape_utils'

def nested_hash_value(obj,key)
  # nested_hash_value(params, ",\"content\":")
  if obj.respond_to?(:key?) && obj.key?(key)
    obj[key]
  elsif obj.respond_to?(:each)
    r = nil
    obj.find{ |*a| r=nested_hash_value(a.last,key) }
    r
  end
end    

extract  = nested_hash_value(params, ",\"content\":")
key      = extract.keys.first
response = JSON.parse EscapeUtils.unescape_javascript(key).gsub(/^"|"$/,'')

这避免了使用邪恶的eval 东西。

更一般地说,我认为您应该以这种方式构建您的处理:

def smell_of_ie_weirdness?
  # Detects whether the request seems like the one sent by IE 10,
  # something like params keys formatting checking etc.
end

def extracted_response
  if smell_of_ie_weirdness?
    # Do weird stuff
    extract_response_for_weird_ie
  else
    # Be clean and polite
    extract_response
  end
end

【讨论】:

  • 非常有创意的回应。谢谢
【解决方案2】:

这给了我一个答案.. 这不是最好的。这绝对是一个黑客。但我觉得这是我唯一得到的东西。

def nested_hash_value(obj,key)
  # nested_hash_value(params, ",\"content\":")
  if obj.respond_to?(:key?) && obj.key?(key)
    obj[key]
  elsif obj.respond_to?(:each)
    r = nil
    obj.find{ |*a| r=nested_hash_value(a.last,key) }
    r
  end
end    


extract      = nested_hash_value(params, ",\"content\":")
key          = extract.keys.first
decoded_hash = key.to_s.gsub(/\\/,'').gsub(/\"/,"'").gsub(/'$|^'/,'').gsub(':','=>')
response     = eval decoded_hash      

如果我在两个输出之间比较==,它们会返回true

然后我就把它全部扔进救援区..

begin
  content = params[:content] || params['content']
  response = JSON.parse(content.first)
rescue
  perform_fd_up_IE_fixer # :)
end

【讨论】:

  • 如果params{"{\"statementId\":"=>{"\"b3dsecret9-bsecret741-23secreta806c\""=>{",\"Content-Type\":"=>{"\"application/json\""=>{",\"content\":"=>{"\\\`malicious_command\\\`"=>{",\"registration\":"=>{"\"27\""=>{",\"AWSAccessKeyId\":"=>{"\"secretIAIVsecretPHsecretQ\""=>{",\"Signature\":"=>{"\"PJ /OW K5secretasyXsecret5A"=>"\"],\"Expires\":[\"1396873090\"],\"Authorization\":[\"\"]}"}}}}}}}}}}}, "method"=>"PUT", "controller"=>"quizzes", "action"=>"statements"} 会怎样(注意malicious_command 部分)
  • 我的想法完全正确.. 我正在退出我正在处理这个问题并处理原始请求的地方。我意识到请求会不一致地改变形状,而且它只是没有加起来。
猜你喜欢
  • 2015-11-26
  • 2011-12-19
  • 2012-02-08
  • 1970-01-01
  • 1970-01-01
  • 2012-11-11
  • 2011-03-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多