【问题标题】:How to parse json of an incoming POST request in Rails?如何在 Rails 中解析传入 POST 请求的 json?
【发布时间】:2010-12-05 17:04:35
【问题描述】:

我有以下问题。 Web 服务正在向我的应用发送 JSON POST 请求,我想解析它。

我以为我可以访问参数

@var = params[:name_of_the_JSON_fields]

但它不起作用。我在 Heroku 日志中看到请求已完成并且参数在那里,但我无法存储它们。

有人有想法吗?

【问题讨论】:

    标签: ruby-on-rails post http-post


    【解决方案1】:

    当您发布 JSON(或 XML)时,rails 将为您处理所有解析,但您需要包含正确的标头。

    让您的应用包含:

    Content-type: application/json
    

    一切都会很酷。

    【讨论】:

    • 对不起,我不明白。你能更具体一点吗?我不想发布 JSON。 Web 服务正在使用 POST 请求访问我的应用程序,我只想从此请求中获取数据,然后对其进行解析。
    • @thomas8877 它没有被解析,因为 Web 服务没有使用正确的内容类型。如果你不能让它使用“application/json”,那么你必须将另一个内容类型关联为 json,这样 Rails 才能理解它需要解析它。
    • 谢谢大家!我必须了解更多关于这个网络服务的东西,因为目前它太复杂了。
    • 这是作者控制请求来源时的最佳方案。但是,这种解决方案在许多情况下是不可能的(您的应用程序正在接收来自外部服务的请求,例如 Amazon SNS)。在这些情况下,请参阅我的答案。
    【解决方案2】:

    这个答案可能并不针对这个确切的问题,但我在设置 AWS SNS 推送通知时遇到了类似的问题。我无法解析甚至查看初始订阅请求。希望这可以帮助其他有类似问题的人。

    我发现如果你有一个简单的 API 设置,默认格式设置为 json,则不需要解析,类似于下面(在 config/routes.rb 中):

     namespace :api, defaults: {format: :json}  do
        namespace :v1 do
          post "/controller_name" => 'controller_name#create'
          get "/controller_name" => 'controller_name#index'
        end
      end
    

    我发现的重要一点是传入的帖子请求可以通过变量request 访问。为了将其转换为可读的 JSON 格式,您可以调用以下代码:

    request.body.read()
    

    【讨论】:

      【解决方案3】:

      在症状描述的大多数情况下,问题的真正根源是传入请求的来源:如果它正在向您的应用发送 JSON,它应该发送 application/json 的 Content-Type 标头。

      如果您能够修改发送请求的应用程序,调整该标头,Rails 会将主体解析为 JSON,一切都会按预期工作,解析后的 JSON 字段会出现在您的 params 哈希中。

      当这不可能时(例如,当您不控制请求的来源时 - 例如接收 Amazon SNS 通知的情况),Rails 不会自动为您将正文解析为 JSON,所以最好你可以自己阅读和解析它,如:

      json_params = JSON.parse(request.raw_post)
      

      【讨论】:

      • 这解决了我的问题。谢谢:“”问题的真正根源是传入请求的来源:如果它正在向您的应用发送 JSON,它应该发送 application/json 的 Content-Type 标头“”
      【解决方案4】:

      如果您在 params 哈希中接收 JSON,您可以自行转换:

      @var = JSON.parse(params[:name_of_the_JSON_fields])
      

      【讨论】:

        【解决方案5】:

        帮助你可能为时已晚,但也许未来的人会在这里检查:) 也许 rails 应该为你解析 json,但这对我来说从来没有用过。我直接阅读了请求正文。我使用'Yajl' json 解析器——它非常快。但是常规的旧 'json' 也可以在这里工作(只需使用 JSON.parse)

        request.body.rewind
        body = Yajl::Parser.parse request.body.read.html_safe
        

        【讨论】:

        • 这不是一个很好的解决方案。因为 request.body 返回一个 StringIO,其字符集设置为 Encoding::BINARY。所以如果你传递一个非 ascii 字符,它会引发一个编码异常
        • 二进制编码不应该能够处理任何类型的字符吗?
        • 不行,它会使用ASCII-8Bit,并尝试将其格式化为utf8..不知道为什么
        • 按照第一个答案的建议设置正确的Content-Type 确实会使rails 自行解析它。不知道为什么你会看到你所看到的。
        猜你喜欢
        • 1970-01-01
        • 2012-01-13
        • 2015-12-23
        • 1970-01-01
        • 2020-02-13
        • 1970-01-01
        • 2018-01-05
        • 2021-10-19
        • 1970-01-01
        相关资源
        最近更新 更多