My application accepts data from POST method which I am running through JQuery's AJAX request. I am sending JSON formatted data, but in handler as I accept request and access the data it turns out to be byte string type.
I am using my_body = self.request.body
method.
For example, if I am sending {"drzava":"rs","kategorija":"general"}
received data looks like b'drzava=rs&kategorija=general'
.
Problem is, afterwards I can't use tornado.escape.json_decode()
, to make it dictionary. I keep getting the following error:
Traceback (most recent call last):
File "/home/stefan/.local/lib/python3.6/site-packages/tornado/web.py", line 1697, in _execute
result = method(*self.path_args, **self.path_kwargs)
File "main.py", line 164, in post
telo_json = tornado.escape.json_decode(telo)
File "/home/stefan/.local/lib/python3.6/site-packages/tornado/escape.py", line 83, in json_decode
return json.loads(to_basestring(value))
File "/usr/lib/python3.6/json/__init__.py", line 354, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3.6/json/decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.6/json/decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
I will post the code, if needed.
UPDATE: Firstly, there was a typo in my .js
file, so AJAX
requests weren't being sent. Secondly, Tornado was detecting default POST
method (not the AJAX
's one), so you have to manually override it by saying something like e.preventDefault();
where e
is parameter of anonymous function in JQUERY
's action. On the other side, in Tornado, result of self.request.body
is something like b'{"country":"rs","category":"sports"}'
which can be transformed to dictionary using tornado.escape.json_decode()
. Many thanks to @Ionut Ticus for constructive suggestions.
So, after bit of investigating and reading docs, I found the following:
HTTPServerRequest.body is now always a byte string (previously the default empty body would be aunicode string on python 3)
This is written it Tornado's official documentation. Tornado Documentation Release 6.0.4 page 183
Hovewer, I found a way around it.
argumenti = self.request.arguments
drzava_val = argumenti['drzava'][0].decode("utf-8")
kategorija_val = argumenti['kategorija'][0].decode("utf-8")
data = {
'drzava': drzava_val,
'kategorija': kategorija_val
}