【问题标题】:HTTP post request via Ruby通过 Ruby 的 HTTP 发布请求
【发布时间】:2011-09-28 19:40:40
【问题描述】:

我对 ruby​​ 非常陌生,并且尝试了一些基本的东西。当我使用以下方式向服务器发送 HTTP 请求时:

curl -v -H "Content-Type: application/json" -X GET -d "{"myrequest":"myTest","reqid":"44","data":{"name":"test"}}" localhost:8099

我的服务器将 JSON 数据视为 "{myrequest:myTest,reqid:44,data:{name:test}}"

但是当我使用以下 ruby​​ 代码发送请求时:

require 'net/http'

@host = 'localhost'
@port = '8099'

@path = "/posts"

@body = ActiveSupport::JSON.encode({
    :bbrequest => "BBTest", 
    :reqid => "44", 
    :data => 
    {
        :name => "test"
    }
})

request = Net::HTTP::Post.new(@path, initheader = {'Content-Type' =>'application/json'})
request.body = @body
response = Net::HTTP.new(@host, @port).start {|http| http.request(request) }
puts "Response #{response.code} #{response.message}: #{response.body}"

它认为它是 "{\"bbrequest\":\"BBTest\",\"reqid\":\"44\",\"data\":{\"name\":\ " test\"}}" 并且服务器无法解析它。也许我需要设置一些额外的选项来从 Ruby 发送请求以排除这些额外的字符?

你能帮忙吗?提前致谢。

【问题讨论】:

  • 不是您的问题的答案,但使用 RestClient 应该可以减少您需要做的工作量,而且我知道它可以轻松发送 JSON:github.com/archiloque/rest-client
  • JSON.parse("{\"bbrequest\":\"BBTest\",\"reqid\":\"44\",\"data\":{\"name\":\" test\"}}") 工作正常你确定你在解析这个字符串吗?
  • 确定问题是转义字符被发送到服务器,而不仅仅是 irb 或 inspect 输出?因为您显示的代码没有放入这些字符。

标签: ruby-on-rails ruby ruby-on-rails-3


【解决方案1】:

您在 shell 上执行的操作会产生无效的 JSON。你的服务器不应该接受它。

  $echo "{"myrequest":"myTest","reqid":"44","data":{"name":"test"}}"
      {myrequest:myTest,reqid:44,data:{name:test}}

这是带有未转义键和值的 JSON,永远不会工作。 http://jsonlint.com/ 如果您的服务器接受这种“某种 JSON”,但在您的示例中不接受第二种 JSON,则您的服务器已损坏。

我的服务器将 JSON 数据视为“{myrequest:myTest,reqid:44,data:{name:test}}”

您的服务器看到一个字符串。当您尝试将其解析为 JSON 时,它会产生错误或垃圾。

它认为它是 "{\"bbrequest\":\"BBTest\",\"reqid\":\"44\",\"data\":{\"name\":\" test\ “}}”

不,这是通过 Ruby 的Object#inspect 打印出来的。您正在某处打印 inspect 的返回值,然后尝试判断它是否是有效的 JSON - 它不是,因为您粘贴的这个字符串被粘贴到交互式 ruby​​ 控制台 (irb) 或 ruby​​ 脚本中,它包含内置的转义。您需要查看原始 JSON 字符串,只需打印字符串而不是检查它。

我认为您的服务器已损坏或尚未完成,您的 curl 示例已损坏并且您的 ruby​​ 脚本是正确的,并且在服务器修复(或完成)后将工作。只是因为

  irb(main):002:0> JSON.parse("{\"bbrequest\":\"BBTest\",\"reqid\":\"44\",\"data\":{\"name\":\" test\"}}")
        # => {"bbrequest"=>"BBTest", "reqid"=>"44", "data"=>{"name"=>" test"}}

【讨论】:

    【解决方案2】:

    您的问题不是字符串中存在转义字符。这些不是由您显示的代码放入的,而是由 irb 或 .inspect 放入的。如果您在代码中输入一个简单的puts @body(或在Rails 上下文中,logger.debug @body),您会看到这一点。这是一个显示差异的 irb 会话:

    ruby-1.9.2-p180 :002 > require 'active_support'
     => true 
    ruby-1.9.2-p180 :003 > json = ActiveSupport::JSON.encode({
    ruby-1.9.2-p180 :004 >           :bbrequest => "BBTest", 
    ruby-1.9.2-p180 :005 >           :reqid => "44", 
    ruby-1.9.2-p180 :006 >           :data => 
    ruby-1.9.2-p180 :007 >           {
    ruby-1.9.2-p180 :008 >                 :name => "test"
    ruby-1.9.2-p180 :009?>           }
    ruby-1.9.2-p180 :010?>     })
     => "{\"bbrequest\":\"BBTest\",\"reqid\":\"44\",\"data\":{\"name\":\"test\"}}" 
    ruby-1.9.2-p180 :013 > puts json
    {"bbrequest":"BBTest","reqid":"44","data":{"name":"test"}}
     => nil 
    

    无论如何,在 Rails 中进行 json 编码的最佳方法不是直接调用 ActiveSupport::JSON.encode,而是在模型中覆盖 as_json 或使用 serializable_hash 功能。这也将使您的代码更干净。有关详细信息,请参阅this stackoverflow question 的热门答案。

    【讨论】:

    • 不,除了上面的代码之外,我没有做任何其他事情。我在我的网页上打印了这个@body,它显示得很好。但是当通过 HTTP 发送时,会得到服务器无法识别的那些额外字符。能否请您转发一些使用 serializable_hash 功能的示例?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-12
    • 1970-01-01
    • 1970-01-01
    • 2013-01-15
    • 2021-07-12
    相关资源
    最近更新 更多