LINUX.ORG.RU

Как преобразовать x-www-form-urlencoded данные в json?

 , , , ,


1

1

Не хочу изобретать велосипед.

Данные с массивами (проклятый php и php-нутые программисты)

contacts%5Bupdate%5D%5B0%5D%5Bid%5D=1526845&contacts%5Bupdate%5D%5B0%5D%5Bname%5D=%D0%A8%D1%82%D0%B5%D0%BF%D0%B0+%D0%95%D0%BB%D0%B5%D0%BD%D0%B0+%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%BE%D0%B2%D0%BD%D0%B0&contacts%5Bupdate%5D%5B0%5D%5Bresponsible_user_id%5D=67&contacts%5Bupdate%5D%5B0%5D%5Bdate_create%5D=1525351212&contacts%5Bupdate%5D%5B0%5D%5Blast_modified%5D=1525453926&contacts%5Bupdate%5D%5B0%5D%5Bcreated_user_id%5D=2360836&contacts%5Bupdate%5D%5B0%5D%5Bmodified_user_id%5D=2360836&contacts%5Bupdate%5D%5B0%5D%5Bcompany_name%5D=%D0%A8%D1%82%D0%B5%D0%BF%D0%B0+%D0%95%D0%BB%D0%B5%D0%BD%D0%B0+%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%BE%D0%B2%D0%BD%D0%B0+%D0%98%D0%9F&contacts%5Bupdate%5D%5B0%5D%5Blinked_company_id%5D=657097&contacts%5Bupdate%5D%5B0%5D%5Bcustom_fields%5D%5B0%5D%5Bid%5D=28719&contacts%5Bupdate%5D%5B0%5D%5Bcustom_fields%5D%5B0%5D%5Bname%5D=%D0%A2%D0%B5%D0%BB%D0%B5%D1%84%D0%BE%D0%BD&contacts%5Bupdate%5D%5B0%5D%5Bcustom_fields%5D%5B0%5D%5Bvalues%5D%5B0%5D%5Bvalue%5D=123&contacts%5Bupdate%5D%5B0%5D%5Bcustom_fields%5D%5B0%5D%5Bvalues%5D%5B0%5D%5Benum%5D=61231&contacts%5Bupdate%5D%5B0%5D%5Bcustom_fields%5D%5B0%5D%5Bcode%5D=PHONE&contacts%5Bupdate%5D%5B0%5D%5Bcustom_fields%5D%5B1%5D%5Bid%5D=28721&contacts%5Bupdate%5D%5B0%5D%5Bcustom_fields%5D%5B1%5D%5Bname%5D=Email&contacts%5Bupdate%5D%5B0%5D%5Bcustom_fields%5D%5B1%5D%5Bvalues%5D%5B0%5D%5Bvalue%5D=234&contacts%5Bupdate%5D%5B0%5D%5Bcustom_fields%5D%5B1%5D%5Bvalues%5D%5B0%5D%5Benum%5D=61243&contacts%5Bupdate%5D%5B0%5D%5Bcustom_fields%5D%5B1%5D%5Bcode%5D=EMAIL&contacts%5Bupdate%5D%5B0%5D%5Btype%5D=contact&account%5Bsubdomain%5D=mail4bvn

Ну ладно, я еще url-decode сделаю

contacts[update][0][id]=1526845&contacts[update][0][name]=Штепа+Елена+Александровна&contacts[update][0][responsible_user_id]=67&contacts[update][0][date_create]=1525351212&contacts[update][0][last_modified]=1525453926&contacts[update][0][created_user_id]=2360836&contacts[update][0][modified_user_id]=2360836&contacts[update][0][company_name]=Штепа+Елена+Александровна+ИП&contacts[update][0][linked_company_id]=657097&contacts[update][0][custom_fields][0][id]=28719&contacts[update][0][custom_fields][0][name]=Телефон&contacts[update][0][custom_fields][0][values][0][value]=123&contacts[update][0][custom_fields][0][values][0][enum]=61231&contacts[update][0][custom_fields][0]

=PHONE&contacts[update][0][custom_fields][1][id]=28721&contacts[update][0][custom_fields][1][name]=Email&contacts[update][0][custom_fields][1][values][0][value]=234&contacts[update][0][custom_fields][1][values][0][enum]=61243&contacts[update][0][custom_fields][1]
=EMAIL&contacts[update][0][type]=contact&account[subdomain]=mail4bvn

Ну а дальше как? парсить строки вручную? попахивает говнокодерством...

ЗЫ. Реализовывать буду на 1С. Возможно, удастся javascript код запустить через какой-нибудь COMОбъект("MSScriptControl.ScriptControl"), поэтому реализации на других языках хоть и интересны, но лишь для того, чтобы я смог потом перегнать в нужный.

ЗЗЫ. Прослойку в виде доп. сервиса тоже не хотелось бы реализовывать...

ЗЗЗЫ. Требуется универсальный метод, т.к. структура данных будет меняться.

★★★★★

Указанный вами урл очень напоминает кодированные данные yii2

Так вот в yii2 оно парсилось както штатно, сейчас не помню

Поэтому посмотрите как оно декодится на стороне сервера

ism ★★★
()

Вот тебе на JavaScript:

let s = 'contacts%5Bupdate%5D%5B0%5D%5Bid%5D=1526845&contacts%5Bupdate%5D%5B0%5D%5Bname%5D=%D0%A8%D1%82%D0%B5%D0%BF%D0%B0+%D0%95%D0%BB%D0%B5%D0%BD%D0%B0+%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%BE%D0%B2%D0%BD%D0%B0&contacts%5Bupdate%5D%5B0%5D%5Bresponsible_user_id%5D=67&contacts%5Bupdate%5D%5B0%5D%5Bdate_create%5D=1525351212&contacts%5Bupdate%5D%5B0%5D%5Blast_modified%5D=1525453926&contacts%5Bupdate%5D%5B0%5D%5Bcreated_user_id%5D=2360836';
let res = s.split('&').map((p) => p.split('=').map((e) => decodeURI(e.replace(/\+/g,' '))));
console.log(res);

парсить строки вручную? попахивает говнокодерством

Нет, это и есть самый простой и прямой способ. Только ты не с того края зашёл — компоненты нужно было декодировать в последнюю очередь. Они кодируются, чтобы все & и =, которые там могли быть, не светились прямым текстом. Поэтому & всегда отделяет пары ключ-значение друг от друга, а = в этих парах отделяет ключ от значения.

Replace там нужен, потому что по какой-то причине decodeURI не понимает, что + декодируется в пробел.

i-rinat ★★★★★
()

В чистом JS такой функции нет, это Web API

https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams

https://nodejs.org/dist/latest-v10.x/docs/api/url.html#url_class_urlsearchparams

поэтому реализации на других языках хоть и интересны, но лишь для того, чтобы я смог потом перегнать в нужный.

Тогда http://php.net/manual/en/function.parse-str.php

surefire ★★★
()
Последнее исправление: surefire (всего исправлений: 1)
Ответ на: комментарий от surefire

Продолжая про PHP, вот так:

$s='contacts%5Bupdate%5D%5B0%5D%5Bid%5D=1526845&contacts%5Bupdate%5D%5B0%5D%5Bname%5D=%D0%A8%D1%82%D0%B5%D0%BF%D0%B0+%D0%95%D0%BB%D0%B5%D0%BD%D0%B0+%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%BE%D0%B2%D0%BD%D0%B0&contacts%5Bupdate%5D%5B0%5D%5Bresponsible_user_id%5D=67&contacts%5Bupdate%5D%5B0%5D%5Bdate_create%5D=1525351212&contacts%5Bupdate%5D%5B0%5D%5Blast_modified%5D=1525453926&contacts%5Bupdate%5D%5B0%5D%5Bcreated_user_id%5D=2360836&contacts%5Bupdate%5D%5B0%5D%5Bmodified_user_id%5D=2360836&contacts%5Bupdate%5D%5B0%5D%5Bcompany_name%5D=%D0%A8%D1%82%D0%B5%D0%BF%D0%B0+%D0%95%D0%BB%D0%B5%D0%BD%D0%B0+%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%BE%D0%B2%D0%BD%D0%B0+%D0%98%D0%9F&contacts%5Bupdate%5D%5B0%5D%5Blinked_company_id%5D=657097&contacts%5Bupdate%5D%5B0%5D%5Bcustom_fields%5D%5B0%5D%5Bid%5D=28719&contacts%5Bupdate%5D%5B0%5D%5Bcustom_fields%5D%5B0%5D%5Bname%5D=%D0%A2%D0%B5%D0%BB%D0%B5%D1%84%D0%BE%D0%BD&contacts%5Bupdate%5D%5B0%5D%5Bcustom_fields%5D%5B0%5D%5Bvalues%5D%5B0%5D%5Bvalue%5D=123&contacts%5Bupdate%5D%5B0%5D%5Bcustom_fields%5D%5B0%5D%5Bvalues%5D%5B0%5D%5Benum%5D=61231&contacts%5Bupdate%5D%5B0%5D%5Bcustom_fields%5D%5B0%5D%5Bcode%5D=PHONE&contacts%5Bupdate%5D%5B0%5D%5Bcustom_fields%5D%5B1%5D%5Bid%5D=28721&contacts%5Bupdate%5D%5B0%5D%5Bcustom_fields%5D%5B1%5D%5Bname%5D=Email&contacts%5Bupdate%5D%5B0%5D%5Bcustom_fields%5D%5B1%5D%5Bvalues%5D%5B0%5D%5Bvalue%5D=234&contacts%5Bupdate%5D%5B0%5D%5Bcustom_fields%5D%5B1%5D%5Bvalues%5D%5B0%5D%5Benum%5D=61243&contacts%5Bupdate%5D%5B0%5D%5Bcustom_fields%5D%5B1%5D%5Bcode%5D=EMAIL&contacts%5Bupdate%5D%5B0%5D%5Btype%5D=contact&account%5Bsubdomain%5D=mail4bvn';

parse_str($s, $a);

$json = json_encode($a);
surefire ★★★
()

В поганом питоне как обычно всё одной строчкой решается: urlparse.parse_qs(...)['def'][0]

anonymous
()
Ответ на: комментарий от bvn13

но я бы хотел эти contacts[update][0] тоже распарсить.

По-нормальному такое уже сложнее. Надо отслеживать все попытки поломать парсер. Но если тяп-ляп, то тоже довольно кратко:

> let s = 'contacts[update][0][id]'
undefined
> s.split('[')[0]
'contacts'
> s.split('[').slice(1).map((e) => e.match(/^(.*)]/)[1])
[ 'update', '0', 'id' ]
> 

i-rinat ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.