От параметров URL (в байтах) до JSON строки - PullRequest
0 голосов
/ 13 апреля 2020

Я использую это для go от параметров URL (полученных в виде байтов в теле HTTP-запроса) до JSON строки:

import urllib.parse, json

def params_asbytes_to_json(b):
    s = b.decode()  # bytes to str
    x = urllib.parse.parse_qsl(s)  # parse_qsl
    d = dict(x)  # convert to dict
    return json.dumps(d)  # convert to string with json 

print(params_asbytes_to_json(b'a=b&c=d'))  # {"a": "b", "c": "d"}

Это работает, но так как задействует многие кодировки / шаги декодирования, я подозреваю, что это неэффективно (если мой сервер получает много запросов).

Есть ли короче / быстрее go от байтов a=b&c=d до JSON строки {"a": "b", "c": "d"}?


PS: эти данные отправляются с HTML <form> следующим образом:

<form action='/do' method='post'>
<input type='text' name='a' value='b'>
<input type='submit'>
</form>

и, для других страниц, через (Vanilla) Javascript:

var xhr = new XMLHttpRequest();
xhr.open("POST", "/do");
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
var fd = new FormData(document.querySelector('form'));
fd.append('dt', +new Date());
xhr.send(new URLSearchParams(fd).toString());

PS: я уже прочитал Как отправить JSON объект, используя html данные формы , но мне нужен мой веб-сайт для работы даже если Javascript отключен , поэтому я не могу на 100% полагаться на XMLHttpRequest + JSON .serialize: он должен работать только с отправкой <form>. Насколько я знаю, стандартная форма HTML не может публиковаться напрямую как JSON, верно?

1 Ответ

0 голосов
/ 13 апреля 2020

Вы можете сохранить один шаг, используя urllib.parse.parse_qs() вместо urllib.parse.parse_qsl(). Он возвращает словарь, а не список, поэтому вам не нужен шаг dict().

Однако, как указано в комментариях, это установит значения словаря в списки, а не в отдельные строки, чтобы разрешить дубликаты ключей в строке запроса. Ваша версия просто отбрасывает дубликаты. Так что либо делайте это по-своему, либо извлекайте элементы из списков в словаре перед вызовом json.dumps().

Вам также не нужно использовать b.decode(). Функции urllib.parse принимают объект bytes и декодируют его.

...