Python запрос Торнадо JSON - PullRequest
0 голосов
/ 29 марта 2020

Мое приложение принимает данные из метода POST, который я выполняю через запрос JQuery AJAX. Я отправляю JSON отформатированные данные, но в обработчике, когда я принимаю запрос и получаю доступ к данным, получается тип строки байтов.

Я использую метод my_body = self.request.body.

Для Например, если я отправляю {"drzava":"rs","kategorija":"general"} полученные данные выглядят как b'drzava=rs&kategorija=general'.

Проблема в том, что впоследствии я не могу использовать tornado.escape.json_decode(), чтобы сделать его словарным. Я продолжаю получать следующую ошибку:

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)

Я отправлю код, если необходимо.

Ответы [ 2 ]

1 голос
/ 30 марта 2020

Данные, которые вы получаете в приложении сервера Tornado, зависят от того, как ваши данные «упаковываются» клиентом.

Вы можете иметь application/x-www-form-urlencoded данные (кажется, ваш случай выше), которые вы можете обработать в Tornado, используя get_body_argument:

drzava = self.get_body_argument("drzava", None)
kategorija = self.get_body_argument("kategorija", None)

или вы можете иметь application/json (кажется чтобы быть нужным вы хотите):

data = tornado.escape.json_decode(self.request.body)

Чтобы отправить JSON данные из вашего браузера, вам нужно фактически отправить JSON data и указать тип содержимого:

var data = {"drzava":"rs", "kategorija":"general"};
$.ajax({
    url: YOUR_URL,
    type: "POST",
    data: JSON.stringify(data),
    contentType: "application/json",
    ...

РЕДАКТИРОВАТЬ:
В итоге проблема заключалась в том, что страница HTML отправляла данные с использованием формы и фактически не использовала код JS.

0 голосов
/ 30 марта 2020

ОБНОВЛЕНИЕ: Во-первых, в моем файле .js была опечатка, поэтому AJAX запросы не отправлялись. Во-вторых, Торнадо обнаружил метод POST по умолчанию (а не AJAX), поэтому вы должны вручную переопределить его, сказав что-то вроде e.preventDefault();, где e - это параметр анонимной функции в JQUERY. действие. С другой стороны, в Tornado результат self.request.body является чем-то вроде b'{"country":"rs","category":"sports"}', который можно преобразовать в словарь, используя tornado.escape.json_decode(). Большое спасибо @Ionut Ticus за конструктивные предложения.

Итак, после небольшого изучения и чтения документов я обнаружил следующее:

HTTPServerRequest.body теперь всегда является байтовой строкой (ранее пустое тело по умолчанию представляло собой строку с юникодом в python 3)

Это написано в официальной документации Торнадо. Документация Tornado, выпуск 6.0.4, стр. 183

Hovewer, я нашел способ обойти это.

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
        }
...