如何在Ruby HTTP请求中的URI中使用方括号[]

时间:2012-01-09 19:52:25

标签: ruby http net-http typhoeus

我使用的API要求我向URL发出请求,其中一个字段作为数组传递。例如:

"http://www.example.com/objects/add.php?key=XXXXXXXXXXX;objects=[%7B%2522field1%2522%253A%2522My%2520ObjectA2%2522%7D%252C%7B%2522field%2522%253A%2522ObjectB%2522%252C%2522color%2522%253A%25221%2522%252C%2522note%2522%253A%252298765%2522%7D];ids=foo,bar" 

如您所见,数组的内容应该是URL编码的,但整个URL不是。是的,我知道这很奇怪,但这是API的设置方式。当我将URI输入Chrome并按Enter键时,它可以工作,但是当我在传递URI之前使用Typhoeus(或net / http)对URI进行编码时,它会失败(请求会通过,但API无法正确识别它)

如何强制Ruby向此URI 发出HTTP请求而不用对方括号进行URL编码?

编辑:这个SO响应看起来很有希望,但我不完全确定如何改变monkeypatching以适应这个例子。

How do I monkey-patch ruby's URI.parse method

1 个答案:

答案 0 :(得分:1)

Typhoeus允许您使用Ruby构造传递HTTP参数。要生成类似于帖子中的URL,您可以执行以下操作:

my_params = { 
              api_key: "XXXXXXXXXXXXXXXXXX",
              objects: [
                { field1: 'My ObjectA2' },
                { field:  'ObjectB',
                  color:  '1',
                  note:   '98765' }],
              ids:  "foo, bar" 
            }


get_response = Typhoeus::Request.get("http://www.example.com/objects/add.php",  params: my_params)
get_response.effective_url #> http://www.example.com/objects/add.php?api_key=XXXXXXXXXXXXXXXXXX&ids=foo%2C+bar&objects=%7B%3Afield1%3D%3E%22My+ObjectA2%22%7D&objects=%7B%3Afield%3D%3E%22ObjectB%22%2C+%3Acolor%3D%3E%221%22%2C+%3Anote%3D%3E%2298765%22%7D

但是,由于您的示例网址包含JSON对象,因此您使用的API似乎更有可能正在寻找POST请求。

post_response = Typhoeus::Request.post("http://www.example.com/objects/add.php", params: my_params)
post_response.effective_url #> http://www.example.com/objects/add.php
post_response.request.params #> {:api_key=>"XXXXXXXXXXXXXXXXXX", :objects=>[{:field1=>"My ObjectA2"}, {:field=>"ObjectB", :color=>"1", :note=>"98765"}], :ids=>"foo, bar"}

修改

如果API需要GET请求,目前通过GET请求传递序列化数据的最常用方法是在参数名称的末尾附加方括号:

http://www.example.com/objects/add.php?objects[]=something&objects[]=something%20else

但是,Typhoeus默认情况下不添加括号。有一些讨论on the Typhoeus mailing list提供了这一决定背后的推理。幸运的是,您可以自己轻松添加括号:

my_params = { 
              api_key: "XXXXXXXXXXXXXXXXXX",
              :"objects[]" => [
                { field1: 'My ObjectA2' },
                { field:  'ObjectB',
                  color:  '1',
                  note:   '98765' }],
              ids:  "foo, bar" 
            }


get_response = Typhoeus::Request.get("http://www.example.com/objects/add.php",  params: my_params)
get_response.effective_url #> http://www.example.com/objects/add.php?api_key=XXXXXXXXXXXXXXXXXX&ids=foo%2C+bar&objects%5B%5D=%7B%3Afield1%3D%3E%22My+ObjectA2%22%7D&objects%5B%5D=%7B%3Afield%3D%3E%22ObjectB%22%2C+%3Acolor%3D%3E%221%22%2C+%3Anote%3D%3E%2298765%22%7D