【问题标题】:How to receive a JSON object with Rack如何使用 Rack 接收 JSON 对象
【发布时间】:2012-03-31 05:04:41
【问题描述】:

我有一个非常简单的 Ruby Rack 服务器,例如:

app = Proc.new do |env| 
  req = Rack::Request.new(env).params
  p req.inspect 
  [200, { 'Content-Type' => 'text/plain' }, ['Some body']]
end 

Rack::Handler::Thin.run(app, :Port => 4001, :threaded => true)

每当我使用 JSON 对象向服务器发送 POST HTTP 请求时:

{ "session": {
"accountId": String,
"callId": String,
"from": Object,
"headers": Object,
"id": String,
"initialText": String,
"parameters": Object,
"timestamp": String,
"to": Object,
"userType": String } } 

我什么也没收到。我可以检测到收到的请求但无法获取数据。我的控制台上puts req.inspect 的结果类似于:

"{}"

我应该如何获取数据?

我试图用类似的东西来改变它:

request  = Rack::Request.new env
object   = JSON.parse request.body
puts JSON.pretty_generate(object)

但我收到以下警告:

!! Unexpected error while processing request: can't convert StringIO into String

【问题讨论】:

  • 发送 JSON 的示例是什么?
  • 没有发送,收到的 JSON 类似于上面带有会话根的示例
  • 好吧,看来我应该使用类似: msg = JSON.parse env['rack.input'].read 然后在 msg hash 中使用 params ,至少它对我有用这边

标签: ruby-on-rails ruby json sinatra rack


【解决方案1】:

另一种方法:

# ...
request  = Rack::Request.new env
object   = JSON.parse request.body.gets
# ...

查看文档:www.rubydoc.info/gems/rack/Rack/Lint/InputWrapper

【讨论】:

    【解决方案2】:

    看来我应该使用类似的东西:

    msg = JSON.parse env['rack.input'].read 
    

    然后在msg 哈希中使用params

    至少它对我有用。

    【讨论】:

    • 如果你看一下env,你会发现一对像这样:"rack.input"=>#<Rack::Lint::InputWrapper:0x007fd293a085d0 @input=#<StringIO:0x007fd2939f1088>>,这意味着你可以将它作为一个IO,所以在它上面使用read方法。
    【解决方案3】:
    env['rack.input'].gets
    

    这对我有用。我发现使用 curl 或 wget 测试针对 Rack (v1.4.1) 服务器的 POST 请求需要使用此代码作为后备来获取请求正文。在野外发布的 POST 请求(例如 GitHub WebHooks)没有同样的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-30
      • 2018-12-29
      • 1970-01-01
      • 2012-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多