Я POST
отправляю JSON через javascript до конечной точки в виде данных формы, а не в теле. Я делаю это, чтобы избежать дополнительного поиска CORS OPTIONS
. JSON отформатирован как:
$.ajax({
url: 'somewhere',
type: 'POST',
data: {
"foo": [
"a",
"b"
],
"bar": [
{
"biz": [
"c",
"d"
]
}
]
},
success: function(response) {
// something
}
});
Когда строка запроса проходит, она выглядит как foo%5B%5D=a&foo%5B%5D=b&bar%5B0%5D%5Bbiz%5D%5B%5D=c&bar%5B0%5D%5Bbiz%5D%5B%5D=d
Я анализирую строку запроса с:
data = parse.unquote(data)
data = parse.parse_qs(data)
print(json.dumps(data))
Но в результате получим dict / json
{
"foo[]": [
"a",
"b"
],
"bar[0][biz][]": [
"c",
"d"
]
}
Это проблематично, так как я не могу пройти оригинальные ключи. Как я могу преобразовать полученное значение обратно в исходную форму JSON?
Это то, что я имею до сих пор
def findValue(value):
if isinstance(value, dict):
value = findValue(list(value.keys())[0])
elif isinstance(value, list):
value = findValue(value[0])
return prepareValue(value)
def prepareKey(data, value=None):
print(data)
if isinstance(data, str):
match = re.findall('([a-zA-Z0-9_-]+)\[([a-zA-Z0-9_-]+)\](.*)', data)
return match[0]
if data[2] != '':
additional = prepareKey(data[2], value)
else:
additional = value
return {data[0]: {data[1]: additional}}
def prepareValue(value):
if len(value) == 1:
value = value[0]
return value
def preparePost(data, newData=False):
if isinstance(data, dict):
if not newData:
newData = {}
for key, value in data.items():
match = re.findall('([a-zA-Z0-9_-]+)\[([a-zA-Z0-9_-]+)\](.*)', key)
if len(match):
assignment = findValue(value)
thisData = prepareKey(match[0], assignment)
newData.update(thisData)
else:
newData[key] = prepareValue(value)
return newData
data = parse.unquote(data)
data = parse.parse_qs(data)
data = preparePost(data)
print(data)
Работает умеренно хорошо, но не подходит для глубоко вложенных значений.
Это реальный запрос, с которым я работаю: foo=bar&cart%5Bcurrency%5D=USD&cart%5Banalytics%5D%5Blib%5D%5Bintegrations%5D%5B0%5D%5Boptions%5D%5BdefaultAttributes%5D%5BthemeId%5D=38654869555&cart%5Banalytics%5D%5Blib%5D%5Bintegrations%5D%5B0%5D%5Boptions%5D%5BdefaultAttributes%5D%5BcontentLanguage%5D=en
Я могу добраться до {'foo': 'bar', 'cart': {'currency': 'USD'}}
, но он не работает cart%5Banalytics%5D%5Blib%5D%5Bintegrations%5D%5B0%5D%5Boptions%5D%5BdefaultAttributes%5D%5BthemeId%5D=38654869555
Решение
Stringify JSON и отправьте правильные заголовки:
$.ajax({
url: 'somewhere',
type: 'POST',
contentType: 'application/x-www-form-urlencoded',
data: JSON.stringify({
"foo": [
"a",
"b"
],
"bar": [
{
"biz": [
"c",
"d"
]
}
]
}),
success: function(response) {
// something
}
});