如何使用Ruby Mechanize gem设置POST请求的主体?我知道你能做到
mechanize.post(url, query, headers)
但是我想用JSON字符串设置POST请求的主体。这可能吗?类似于jQuery:
$.ajax({
type: 'POST',
url: 'myurl',
data: "{'key1':'value1','key2':'value2'}",
...
});
我真的不喜欢你在评论中链接到的答案,因为它采用了to_json(),这是一个rails方法,你的问题的标签并不表明你的问题属于rails。无论如何,我认为答案需要讨论。
下面是机械化方法:
Mechanize#post(url, query, headers)
…你的目标是:
我想设置POST请求的主体
Mechanize#post()允许您将请求的主体设置为您想要的任何内容,但您还必须考虑以下问题:
What is the server side expecting?
您给出了一个jquery ajax()请求的示例,用于您想要做的事情。jquery在发送ajax()请求时使用以下默认的Content-Type标头:
application/x-www-form-urlencoded; charset=UTF-8
告诉服务器post请求的主体将以特定的密码编写。好吧,这不是什么秘密;它看起来像这样:
name1=val1&name2=val2
这个密码的名字是x-www-form-urlencoded
。由于在Content-Type报头中为服务器提供了秘密代码的名称,因此服务器知道如何读取post请求的正文。
在Mechanize#post()方法中,第二个参数是'query', Mechanize文档对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将'query'哈希转换为使用名为x-www-form-urlencoded
的秘密代码的字符串,并将字符串插入post请求的主体。在服务器端,接收post请求的应用程序可以像这样检索json字符串:
json_str = post_variables['data']
你应该知道还有其他的秘密代码可以用于post请求的主体。其中一个名为json
,它是使用javascript语法格式化的字符串,例如:
'{
"id": 1,
"name": "A green door",
"price": 12.50,
"tags": ["home", "green"]
}'
请注意json格式中没有'='符号或'&'符号-与x-www-form-urlencoded
格式一样,因此json
密码与x-www-form-urlencoded
密码有很大不同。
如果你想在post请求的主体中使用json
密码,你需要在调用Mechanize#post(url, query, headers)
时改变两件事:
- 为'query'参数提供一个字符串
- 告诉服务器post请求正文使用
json
秘码
:
json_str = '{"key1":"value1","key2":"value2"}'
my_agent.post(
'http://target_site.com',
json_str,
{'Content-Type' => 'application/json'},
)
当您为查询参数传递String参数时,Mechanize在将String插入post请求的主体之前不会对String进行任何处理。在服务器端,接收post请求的应用程序可以通过以下操作检索json字符串:
json_str = request.body.read
#Then probably:
hash = JSON.parse(json_str)
一个问题是服务器可以忽略Content-Type报头,并尝试使用它已经确定的秘密代码读取post请求的正文。如果您的post请求的主体不是用服务器期望的秘密代码编写的,那么您将得到一个错误。
请注意,你发布的'data'字符串不是有效的json,因为它使用单引号的属性和值。