如何使用Ruby Mechanize设置POST请求的主体?
如何使用Ruby Mechanize gem设置POST请求的主体。我知道你能行如何使用Ruby Mechanize设置POST请求的主体?,ruby,mechanize-ruby,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'}", ... }); 我真的不喜欢你在评论中链接到的答案,因为它使用了
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请求的主体
机械化后()允许你将请求的主体设置成你想要的任何东西,但是你也必须考虑这个问题:
What is the server side expecting?
您给出了一个jquery ajax()请求示例,以了解您想要做什么。jquery在发送ajax()请求时使用以下默认内容类型头:
这告诉服务器post请求的主体将被写入特定的密码中。嗯,这不是什么秘密;看起来是这样的:
name1=val1&name2=val2
该密码的名称是x-www-form-urlencoded
。因为服务器在内容类型头中被赋予了密码的名称,所以服务器知道如何读取post请求的主体
在Mechanize#post()方法中,第二个参数是'query',Mechanize文档对查询参数这样说:
查询由字符串指定,或
由哈希表示的键值对列表,或
数组的数组
如果您想在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'},
)
json_str = post_variables['data']
json_str = request.body.read
#Then probably:
hash = JSON.parse(json_str)
然后,Mechanize将使用名为x-www-form-urlencoded
的密码将“query”散列转换为字符串,并将该字符串插入post请求的正文中。在服务器端,接收post请求的应用程序可以通过如下方式检索json字符串:
my_agent.post(
'http://target_site.com',
my_hash,
{'Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8'},
)
json_str = post_variables['data']
json_str = request.body.read
#Then probably:
hash = JSON.parse(json_str)
您应该知道,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、查询、标题)
时需要更改两件事:
json
密码json_str = '{"key1":"value1","key2":"value2"}'
my_agent.post(
'http://target_site.com',
json_str,
{'Content-Type' => 'application/json'},
)
为查询参数传递字符串参数时,Mechanize在将字符串插入post请求主体之前不会对该字符串进行任何处理。在服务器端,接收post请求的应用程序可以通过如下操作检索json字符串:
my_agent.post(
'http://target_site.com',
my_hash,
{'Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8'},
)
json_str = post_variables['data']
json_str = request.body.read
#Then probably:
hash = JSON.parse(json_str)
一个缺陷是服务器可以忽略Content-Type头,并尝试使用它已经决定的密码读取post请求的主体。如果post请求的主体没有使用服务器期望的密码写入,那么您将得到一个错误
请注意,您发布的“数据”字符串不是有效的json,因为它在属性和值周围使用单引号。这似乎是答案,我在发布前错过了它:-如果这个问题应该关闭,这对meMy来说没关系json字符串非常小且扁平,所以我只是手动生成它,但你是对的,我的问题更一般。还有,关于json无效的一点很好,我甚至没有意识到,因为我发送它的服务器已经接受了它。@RTF,我想你实际上看到的是你在评论中链接到的问题中未接受的答案。显然,这是设置post请求主体的另一种方法。@RTF,在您的ajax()示例中,jquery文档说,如果“数据”是字符串(如您所指定的),那么jquery将不会将字符串处理为
x-www-form-urlencoded
格式,因此我回答的部分前提就不存在了。我猜,因为jquery示例没有指定contentType属性,您最终会得到默认的Content-Type头application/x-www-form-urlencoded
,但帖子正文将采用json
格式,这可能会使服务器出错。在任何情况下,您的jquery示例都充分展示了您想要做的事情——我只是误解了它……请注意,jquery ajax()“data”属性的工作原理与Mechanize#post()“query”参数类似:如果您提供了一个对象/散列,那么对象/散列将转换为x-www-urlencoded
格式的字符串;如果您提供了一个字符串,它将被插入到请求的主体中而不被触及。