我不太喜欢您在评论中链接到的答案,因为它使用了一个 rails 方法的 to_json(),并且您问题的标签并不表明您的问题与 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
这告诉服务器发布请求的主体将被写入特定的密码。好吧,这不是什么秘密。它看起来像这样:
name1=val1&name2=val2
那个密码的名字是x-www-form-urlencoded。因为在 Content-Type 标头中为服务器提供了密码的名称,所以服务器知道如何读取 post 请求的正文。
在 Mechanize#post() 方法中,第二个参数是“查询”,机械化文档对查询参数是这样说的:
查询由字符串或
指定
由散列表示的键值对列表,或
数组数组。
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 的密码将“查询”哈希转换为字符串,并将该字符串插入到发布请求的正文中。在服务器端,接收到 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 密码有很大不同.
如果你想在你的 post 请求正文中使用 json 密码,你需要在调用 Mechanize#post(url, query, headers) 时更改两件事:
- 为“查询”参数提供一个字符串。
- 告诉服务器 post 请求的正文使用
json 密码。
像这样:
json_str = '{"key1":"value1","key2":"value2"}'
my_agent.post(
'http://target_site.com',
json_str,
{'Content-Type' => 'application/json'},
)
当您为查询参数传递一个字符串参数时,Mechanize 在将字符串插入到 post 请求的正文之前不会对字符串进行任何处理。在服务器端,接收到 post 请求的应用程序可以通过执行以下操作来检索 json 字符串:
json_str = request.body.read
#Then probably:
hash = JSON.parse(json_str)
一个问题是服务器可以忽略 Content-Type 标头并尝试使用它已经确定的密码来读取发布请求的正文。如果您的 post 请求正文没有写入服务器期望的密码,那么您将收到错误。
请注意,您发布的“数据”字符串不是有效的 json,因为它在属性和值周围使用单引号。