如何使用Ruby Mechanize设置POST请求的主体?

时间:2014-08-15 15:33:28

标签: ruby mechanize-ruby

如何使用Ruby Mechanize gem设置POST请求的主体。我知道你可以做到

mechanize.post(url, query, headers)

但我想用JSON字符串设置POST请求的主体。那可能吗?所以,类似于jQuery这样的东西:

$.ajax({
    type: 'POST',
    url:  'myurl',
    data: "{'key1':'value1','key2':'value2'}",
    ...
});

1 个答案:

答案 0 :(得分:8)

我不太喜欢你在评论中链接到的答案,因为它使用to_json()这是一种rails方法,而你问题的标签并不表示你的问题属于rails。无论如何,我认为答案需要一些讨论。

这是机械化方法:

Mechanize#post(url, query, headers)

......你的既定目标是:

  

我想设置POST请求的正文

Mechanize#post()允许您将请求的主体设置为您想要的任何内容,但您还必须考虑以下问题:

What is the server side expecting?  

您举例说明了您想要执行的jquery ajax()请求。发送ajax()请求时,jquery使用以下默认Content-Type标头:

application/x-www-form-urlencoded; charset=UTF-8

告诉服务器,post请求的主体将以特定的密码写入。嗯,这不是什么秘密;它看起来像这样:

name1=val1&name2=val2

该密码的名称为x-www-form-urlencoded。因为服务器在Content-Type标头中被赋予了密码的名称,所以服务器知道如何读取发布请求的主体。

在Mechanize#post()方法中,第二个参数是' query',机械化文档说明了查询参数:

  

查询由字符串

指定      

哈希

表示的键值对列表      

数组数组

http://rubydoc.info/gems/mechanize/Mechanize#post-instance_method

如果要在Mechanize#post()请求的主体中使用名为x-www-form-urlencoded的密码,则可以提供具有名称/值对的哈希,例如

my_hash = {
  'data' => '{"key1":"value1","key2":"value2"}'
}

然后你像这样调用Mechanize#post():

my_agent.post(
  'http://target_site.com', 
  my_hash, 
  {'Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8'},
)

然后,Mechanize会转换'查询'使用名为x-www-form-urlencoded的密码将哈希值转换为String,并将该字符串插入到post请求的正文中。在服务器端,接收post请求的应用程序可以检索json字符串,执行以下操作:

json_str = post_variables['data']   

您应该知道还有其他密码可以用于邮寄请求的正文。其中一个名为json,它是使用javascript语法格式化的字符串,例如:

  '{
    "id": 1,
    "name": "A green door",
    "price": 12.50,
    "tags": ["home", "green"]
  }'

请注意没有' ='标志或'&' json格式的符号 - 与x-www-form-urlencoded格式一样,因此json密码与x-www-form-urlencoded密码有很大不同。

如果您想在帖子请求的正文中使用json密码,则在致电Mechanize#post(url, query, headers)时需要更改两件事:

  1. 为查询提供字符串'参数。
  2. 告诉服务器发布请求的正文使用json密码。
  3. 像这样:

    json_str = '{"key1":"value1","key2":"value2"}'
    
    my_agent.post(
      'http://target_site.com', 
      json_str, 
      {'Content-Type' => 'application/json'},
    )
    

    当您为查询参数传递String参数时,在将String插入到post请求的主体之前,Mechanize不会对String进行任何处理。在服务器端,接收post请求的应用程序可以通过执行以下操作来检索json字符串:

    json_str = request.body.read
    #Then probably:
    hash = JSON.parse(json_str)
    

    一个问题是服务器可以忽略Content-Type标头并尝试使用已经决定的密码来读取post请求的主体。如果您的发布请求的正文未写入服务器所需的密码,那么您将收到错误。

    请注意'数据'你发布的字符串不是有效的json,因为它在属性和值周围使用单引号。