How do I set the body of a POST request using Ruby Mechanize?

How can you set POST request body using Ruby Mechanize gem. I know what you can do

mechanize.post(url, query, headers)

      

but I want to set the body of the POST request with a JSON string. Is it possible? So it looks like something like this with jQuery:

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

      

+3


source to share


1 answer


I don't like the answer you link to in your comment because it uses to_json (), which is a rails method, and the tags for your question do not indicate that your question is rails. Anyway, I think the answer needs some discussion.

Here is the mechanization method:

Mechanize#post(url, query, headers)

      

... and your stated goal:

I want to set POST request body

Mechanize # post () allows you to set the request body to whatever you want, but you should also consider:

What is the server side expecting?  

      

You have given an example jquery ajax () request for what you want to do. jquery uses the following Content-Type header by default when sending an ajax () request:

application/x-www-form-urlencoded; charset=UTF-8

      

This tells the server that the body of the mail request will be written in a specific secret. Well, it's not a secret; it looks like this:

name1=val1&name2=val2

      

This is a secret codename x-www-form-urlencoded

. Since the server has been assigned the passcode name in the Content-Type header, the server knows how to read the post request body.

In the Mechanize # post () method, the second parameter is "request" and the mechanization docs say about this request argument:

The request is specified either as a string or

a list of key-value pairs represented by the hash , or

array of arrays .

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

If you want to use a passcode with a name x-www-form-urlencoded

in the body of your Mechanize # post () request, you can provide hashing with name / value pairs, eg.



my_hash = {
  'data' => '{"key1":"value1","key2":"value2"}'
}

      

Then you call Mechanize # post () like this:

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

      

Mechanize then converts the "query" Hash to a string using the passcode named x-www-form-urlencoded

and inserts the string into the body of the post request. On the server side, the application that receives the post request can retrieve the json string by doing something like this:

json_str = post_variables['data']   

      

You should be aware that there are other secret codes that can be used for the body of the mail request. One of them is called json

, which is a string formatted using javascript syntax, for example:

  '{
    "id": 1,
    "name": "A green door",
    "price": 12.50,
    "tags": ["home", "green"]
  }'

      

Note that there are no '=' or '&' symbols in the json format - as it is in the format x-www-form-urlencoded

, so the passcode is json

very different from the passcode x-www-form-urlencoded

.

If you want to use the passcode json

in the body of your post request, you need to change two things when you call Mechanize#post(url, query, headers)

:

  • Provide a string for the request argument.
  • Tell the server that the body of the mail request is using a passcode json

    .

Like this:

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

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

      

When you pass a String argument for a request parameter, Mechanize does no processing of the String before inserting the String into the body of the post request. On the server side, the application that receives the post request can get the json string by doing something like this:

json_str = request.body.read
#Then probably:
hash = JSON.parse(json_str)

      

One problem is that the server might ignore the Content-Type header and try to read the message request body using the passcode it already accepted. If the body of your mail request is not written in the secret code expected by the server, you will receive an error message.

Note that the string "data" you posted is not valid json because it uses single quotes around properties and values.

+6


source







All Articles