Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does jquery post json as a parameter name instead of as the request body?

For a webapp with a RESTful backend I am posting some json to the server using jquery's $post. Now to my surprise, the json is stuffed in a parameter key for the request's form data, instead of in the request body. I can think of some other ways to do it, but the question is why it doesn't work as I expect.

On the server I use scalatra and print some request info:

println("Request received:")
println(fromInputStream(request.getInputStream).getLines().mkString)
println("--------------")
println(request.getParameterMap.toString)
println("==============")

Now a simple curl that does what I think is right:

curl -X POST http://localhost:8080/x -H "Content-Type: application/json" -d '{"a":"b"}'

Produces:

Request received:
{"a":"b"}
-------------
{}
==============

And the bit of html+js to illustrate the problem:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<body>
  <button type="button" onclick="doPost()">
    POST
  </button>
  <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
  <script type="text/javascript">
function doPost() {
    $.post("http://localhost:8080/x",     
           JSON.stringify({"a":"b"} ), 
           function(data) {});
}
  </script>
</body>
</html>

Produces:

Request received:

--------------
{{"a":"b"}=[Ljava.lang.String;@7a2897ac}
============== 

So if I use $post with a stringified json string and a callback I get everything stuffed in a single parameter key. If this is normal, I would like to know why, and how I'm supposed to unravel this cleanly on the server. If it is not normal, I'd like to know what I should do to to get it in the response body using $post.

UPDATE: There is now a feature request for jquery to support contentType on $.post

like image 915
iwein Avatar asked Jan 06 '12 12:01

iwein


People also ask

Can you send data in a GET request?

Can I send data using the HTTP GET method? No, HTTP GET requests cannot have a message body. But you still can send data to the server using the URL parameters. In this case, you are limited to the maximum size of the URL, which is about 2000 characters (depends on the browser).

What is jQuery post?

jQuery post() Method post() method loads data from the server using a HTTP POST request.

What is data in Ajax jQuery?

It is converted to a query string, if not already a string. It's appended to the url for GET-requests. See processData option to prevent this automatic processing. Object must be Key/Value pairs. If value is an Array, jQuery serializes multiple values with same key based on the value of the traditional setting.


2 Answers

I think you can do this if you drop down to $.ajax

$.ajax(
  {
     url: "http://localhost:8080/x",
     data: JSON.stringify({a: 'b'}),
     processData: false,
     type: 'POST',
     contentType: 'application/json'
  }
);

processData tells jquery not to mess around with your data and setting contentType should ensure that your backend doesn't try and parse the json as it were a regular url encoded form.

like image 96
Frederick Cheung Avatar answered Nov 11 '22 19:11

Frederick Cheung


You are not setting the content-type which is causing the $.post() method to set it to application/x-www-form-urlencoded.

Use $.ajax() and set the content-type to application/json explicitly.

Regards, Vincent.

like image 22
Vincent Partington Avatar answered Nov 11 '22 17:11

Vincent Partington