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

RTF*_*RTF 4 ruby mechanize-ruby

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

mechanize.post(url, query, headers)
Run Code Online (Sandbox Code Playgroud)

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

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

7st*_*tud 9

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

这是机械化方法:

Mechanize#post(url, query, headers)
Run Code Online (Sandbox Code Playgroud)

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

我想设置POST请求的主体

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

What is the server side expecting?  
Run Code Online (Sandbox Code Playgroud)

您给出了一个jquery ajax()请求示例,表示您要执行的操作.发送ajax()请求时,jquery使用以下默认Content-Type标头:

application/x-www-form-urlencoded; charset=UTF-8
Run Code Online (Sandbox Code Playgroud)

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

name1=val1&name2=val2
Run Code Online (Sandbox Code Playgroud)

那个密码的名字是x-www-form-urlencoded.因为服务器在Content-Type标头中被赋予了密码的名称,所以服务器知道如何读取post请求的主体.

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

查询由字符串或或指定

哈希表示的键值对列表,或

数组数组.

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

如果要使用在x-www-form-urlencodedMechanize#post()请求正文中指定的密码,则可以提供具有名称/值对的哈希,例如

my_hash = {
  'data' => '{"key1":"value1","key2":"value2"}'
}
Run Code Online (Sandbox Code Playgroud)

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

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

然后,Mechanize将使用命名的密码将'query'Hash转换为String x-www-form-urlencoded,并将该字符串插入post请求的主体中.在服务器端,接收post请求的应用程序可以检索json字符串,执行以下操作:

json_str = post_variables['data']   
Run Code Online (Sandbox Code Playgroud)

您应该知道,还有其他密码可用于发布请求的正文.其中一个被调用json,这是一个使用javascript语法格式化的字符串,例如:

  '{
    "id": 1,
    "name": "A green door",
    "price": 12.50,
    "tags": ["home", "green"]
  }'
Run Code Online (Sandbox Code Playgroud)

请注意json格式中没有'='符号或'&'符号 - 因为x-www-form-urlencoded格式有,所以json密码与密码有很大不同x-www-form-urlencoded.

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

  1. 为'query'参数提供一个String.
  2. 告诉服务器post请求的主体使用json密码.

像这样:

json_str = '{"key1":"value1","key2":"value2"}'

my_agent.post(
  'http://target_site.com', 
  json_str, 
  {'Content-Type' => 'application/json'},
)
Run Code Online (Sandbox Code Playgroud)

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

json_str = request.body.read
#Then probably:
hash = JSON.parse(json_str)
Run Code Online (Sandbox Code Playgroud)

在一个结是服务器可以忽略Content-Type头,并尝试读取使用一个密码,它已经定下来后请求的主体.如果您的发布请求的正文未写入服务器所需的密码,那么您将收到错误消息.

请注意,您发布的'data'字符串无效json,因为它在属性和值周围使用单引号.

  • ...请注意,jquery ajax()'data'属性的工作方式类似于Mechanize#post()'query'参数:如果提供了一个对象/ Hash,则对象/ Hash将转换为`x-www中的字符串-urlencoded`格式; 如果你提供一个字符串,它会被插入到请求的主体中. (2认同)