4

I need some help with getting json data in flask from jquery ajax.

Below client side javascript which gets called whenever some button is clicked.

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
    function change_status(item, status) {
          var statusObj={"desc":item, "status":status};
          $.ajax({
                    url:"/robot/api/"+item,
                    type: "PUT",
                    contentType:"applicaton/json",
                    dataType:"json",
                    data: JSON.stringify(statusObj)
          });
    }
</script>

on server side(flask), I have below code to catch json data.

@app.route('/robot/api/<item>', methods = ['PUT'])
def update_item(item):

print "content_type: ", request.content_type

print "request.json: ", request.json

if not request.json:
    print "bad json format"
    abort(400)
else
    """
    do something like update data
    """

In PC, when clicking button in the browser which calls javascript function, flask server is printing below message:

"content_type:  applicaton/json; charset=UTF-8

request.json:  None

bad json format

192.168.1.241 - - [12/Feb/2014 15:06:16] "PUT /robot/api/3g HTTP/1.1" 400 -"

It shows request.content_type is json but when actually printed it says None.

I did packet capture to see data from PC with wireshark and I see below:

From PC to Flask Server:

PUT /robot/api/3g HTTP/1.1

Host: "my flask server ip address"

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0

Accept: application/json, text/javascript, */*; q=0.01

Accept-Language: en-US,en;q=0.5

Accept-Encoding: gzip, deflate

Content-Type: applicaton/json; charset=UTF-8

X-Requested-With: XMLHttpRequest

Referer: "my flask server ip address"

Content-Length: 28

Connection: keep-alive

{"desc":"3g","status":"off"}

But Flask server returns "HTTP/1.0 400 BAD REQUEST"

codegeek
  • 32,236
  • 12
  • 63
  • 63
user3022431
  • 63
  • 1
  • 1
  • 5

1 Answers1

6

The issue here is that you are missing the "i" in "application/json". Change your jQuery call to contentType:"application/json" (rather than contentType:"applicaton/json") and everything should work just fine.

Flask only loads the payload in the request body as JSON if the content type is application/json - anything else and you have to load the JSON yourself, using request.get_json(force=True)

Sean Vieira
  • 155,703
  • 32
  • 311
  • 293
  • Thanks Sean, You're right. I'll so stupid. wasted 2 days of my evening time for simple mistake... – user3022431 Feb 13 '14 at 05:08
  • This works! But `Content-Type` is widely spreaded (which is not recognized by Flask), what is the standard? – Frozen Flame Jan 02 '15 at 08:15
  • @FrozenFlame - [the standard is application/json](http://stackoverflow.com/a/477819/135978) – Sean Vieira Jan 02 '15 at 17:08
  • @SeanVieira Thanks. But I meant, `Content-Type` or `contentType` o r `ContentType`. camelCase or Dash-separated? Case sensitive or not? – Frozen Flame Jan 03 '15 at 05:36
  • HTTP headers [are not case sensitive](http://stackoverflow.com/a/5259004/135978) but they must be dash-separated. Other languages and frameworks will change how the keys are handled to make it more convenient to access *from the language in question* - in jQuery's case, being JavaScript they use the camelCase variant because it doesn't need to be quoted when used as a key. – Sean Vieira Jan 03 '15 at 21:13