如何使用Ruby Mechanize gem设置POST请求的主体。我知道你可以做到
mechanize.post(url, query, headers)
但我想用JSON字符串设置POST请求的主体。那可能吗?所以,类似于jQuery这样的东西:
$.ajax({
type: 'POST',
url: 'myurl',
data: "{'key1':'value1','key2':'value2'}",
...
});
答案 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)
时需要更改两件事:
json
密码。像这样:
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,因为它在属性和值周围使用单引号。