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

3

6

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

Clamorous answered 6/1, 2012 at 12:16 Comment(0)
G
10

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.

Groot answered 6/1, 2012 at 12:25 Comment(0)
T
4

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.

Tablespoon answered 6/1, 2012 at 12:28 Comment(0)
M
0

Vincent Partington is right, the default contentType is set to application/x-www-form-urlencoded

Use the jQuery.ajax function directly instead or create your own shorthand.

You can also change the server side, see Spring 3 MVC - Advanced Data Binding - Form Request with List of Simple Objects for example. But I would just use the full ajax function.

Micrometer answered 6/1, 2012 at 12:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.