Декодирование form-urlencoded (application/x-www-form-urlencoded) тела запроса

10.12.24

Разработка - Универсальные функции

Функция декодирования form-urlencoded строк данных.

В 1С нет встроенной функции для разбора application/x-www-form-urlencoded строки параметров, которая обычно передается из HTML форм и выглядит вот так:

login=smith&password=12345678

Казалось бы, все просто, но некоторые сервисы умудряются отправлять в такой строке большое количество разнообразных данных, в том числе и массивы объектов. Например, вот так:

 custom_fields[0][name]=а0&custom_fields[0][value]=b0&custom_fields[1][name]=а1&custom_fields[1][value]=b1

Прилагаю функцию декодирования application/x-www-form-urlencoded строки параметров в соответствие. Поддерживается декодирование массивов простых значений, массивов свойств вида custom_fields[0][name]=а и вложенных массивов.

Функция ПолучитьСоответствиеИзFormUrlEncoded(ТелоЗапроса)
	
	Результат = Новый Соответствие;      
	
	ТекстЗапроса 		= РаскодироватьСтроку(ТелоЗапроса, СпособКодированияСтроки.КодировкаURL, "UTF-8");
	ТекстЗапроса 		= СтрЗаменить(ТекстЗапроса, "+", " ");
	ТекстЗапроса 		= СтрЗаменить(ТекстЗапроса, "u'", "'");
	ПараметрыИЗначения 	= СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(ТекстЗапроса, "&");
	
	Для Каждого ПараметрИЗначение Из ПараметрыИЗначения Цикл   
		
		ПозицияРавно = Найти(ПараметрИЗначение, "=");   
		Если ПозицияРавно > 0 Тогда
			Параметр = Лев(ПараметрИЗначение, ПозицияРавно - 1);
			Значение = Прав(ПараметрИЗначение, СтрДлина(ПараметрИЗначение) - ПозицияРавно);
			
			//Например: custom_fields[0][name]
			Если Найти(Параметр, "[") > 0 Тогда
				ДанныеСоставногоПараметра 	= СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(
													СтрЗаменить(Параметр, "]", ""), "[");
				СоставнойПараметр 			= ДанныеСоставногоПараметра[0];
				
				СоответствиеСтрокПараметра = Результат.Получить(СоставнойПараметр);
				Если СоответствиеСтрокПараметра = Неопределено Тогда
					СоответствиеСтрокПараметра = Новый Соответствие;
					Результат.Вставить(СоставнойПараметр, СоответствиеСтрокПараметра);	
				КонецЕсли;
				Если ДанныеСоставногоПараметра.Количество() > 2 Тогда   
					СоответсвиеСвойствПараметра = СоответствиеСтрокПараметра.Получить(ДанныеСоставногоПараметра[1]);
					Если СоответсвиеСвойствПараметра = Неопределено Тогда
						СоответсвиеСвойствПараметра = Новый Соответствие();
						СоответствиеСтрокПараметра.Вставить(ДанныеСоставногоПараметра[1], СоответсвиеСвойствПараметра);
					КонецЕсли;  
					Параметр = ДанныеСоставногоПараметра[2];
					СоответствиеПараметрЗначение = СоответсвиеСвойствПараметра;
				Иначе                                  
					Параметр = ДанныеСоставногоПараметра[1];
					СоответствиеПараметрЗначение = СоответствиеСтрокПараметра;
				КонецЕсли;     
			Иначе 
				СоответствиеПараметрЗначение = Результат;
			КонецЕсли;
			
			ПредыдущееЗначение = СоответствиеПараметрЗначение.Получить(Параметр);   
			Если ПредыдущееЗначение = Неопределено Тогда
				СоответствиеПараметрЗначение.Вставить(Параметр, Значение);	
			Иначе
				Если ДанныеСоставногоПараметра = Неопределено Тогда 
					Если ТипЗнч(ПредыдущееЗначение) = Тип("Массив") Тогда 
						Если ПредыдущееЗначение.Найти(Значение) = Неопределено Тогда 
							ПредыдущееЗначение.Добавить(Значение);
						КонецЕсли;
					Иначе                                                     
						//Если это второе значение параметра, то добавляем уже существующее и текущее
						//значение в массив, если они отличаются.	
						Если ПредыдущееЗначение <> Значение Тогда
							МассивЗначений = Новый Массив();
							МассивЗначений.Добавить(ПредыдущееЗначение);
							МассивЗначений.Добавить(Значение);
							СоответствиеПараметрЗначение.Вставить(Параметр, МассивЗначений);
						КонецЕсли;
					КонецЕсли;
				КонецЕсли;
			КонецЕсли;
		Иначе
			Результат.Вставить(ПараметрИЗначение, Неопределено);
		КонецЕсли;
	КонецЦикла;
	
	Возврат Результат;
	
КонецФункции

 

Другие публикации

См. другие публикации автора:

Дебиторская задолженность по срокам долга

Кредиторская задолженность по срокам долга

Контактная информация на мобильном телефоне

Когда много сканов: Автоматическое прикрепление сканированных документов

Когда много строк в документе: Удобный редактор табличных частей

Перенос справочников и документов из КА 1.1. в ЗУП 3.1.

Статистика документов на СКД для любой конфигурации

form-urlencoded декодирование

См. также

Взаиморасчеты Бухгалтер Пользователь Платформа 1С v8.3 1С:Комплексная автоматизация 1.х 1С:Управление торговлей 10 1С:Управление производственным предприятием 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Бухгалтерский учет Управленческий учет Платные (руб)

Один из лучших вариантов отчета по дебиторской задолженности в 1С. Отображает сроки возникновения задолженности, просроченной задолженности с точностью до регистратора, а также многое другое, вне зависимости от объекта расчетов (УТ 11.3, 11.4, 11.5, КА 2.4, 2.5, ERP 2.4, 2.5), состояния флажка По документам расчета ( УТ 10, КА 1.1, УПП 1.3) в договоре. Группирует задолженность по интервалам. Имеет большое количество настроек. Не требует доработок конфигурации. Не требует перепроведения документов.

15120 руб.

28.09.2012    97467    594    288    

145

SALE! 40%

Учет документов Распознавание документов и образов Бухгалтер Пользователь Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Платные (руб)

Одна из наиболее удобных обработок автоматического прикрепления большого количества документов-оригиналов к документам 1С. Для файлов поточного сканирования автоматически определяются начало и конец каждого документа. Поддерживаются штрихкоды, QR-коды, отсканированные PDF документы без штрихкодов, сформированные в ЭДО текстовые PDF документы. Поддерживаются входящие и исходящие документы-оригиналы.

6480 руб.

23.12.2021    13304    16    25    

10

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

21.05.2024    22747    dimanich70    81    

147

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    4289    3    John_d    11    

57

Универсальные функции Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    21798    atdonya    25    

58

Универсальные функции Программист Платформа 1С v8.3 Бесплатно (free)

На заключительных этапах, когда идет отладка или доработка интерфейса, необходимо много раз переоткрыть внешний объект. Вот один из способов автоматизации этого.

30.11.2023    5791    ke.92@mail.ru    17    

65

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    15712    YA_418728146    8    

170
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. RocKeR_13 1376 10.12.24 15:14 Сейчас в теме
А вот тут

ПозицияРавно = Найти(ПараметрИЗначение, "=");


почему не использовали

СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(ПараметрИЗначение, "=");


Раз уж решили использовать БСП, то держите еще лайфхак:

РаботаСФормуламиКлиентСервер.ОперандыТекстовойФормулы


Для строки "custom_fields[0][value]" вернет массив из элементов:

0 - "0"
1 - "value"

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

ИмяПараметра 	= "custom_fields[0][value]";
МассивЗначений = РаботаСФормуламиКлиентСервер.ОперандыТекстовойФормулы(ИмяПараметра);

Для Каждого Операнд Из МассивЗначений Цикл
	
	ПодстрокаЗамены = РаботаСФормуламиКлиентСервер.ПолучитьТекстОперандаДляВставки(Операнд);
	ИмяПараметра 	= СтрЗаменить(ИмяПараметра, ПодстрокаЗамены, "");
	
КонецЦикла;
Показать
3. bme 232 11.12.24 06:44 Сейчас в теме
(1) Да, так тоже можно собрать массив свойств, спасибо за подсказку!
2. bayselonarrend 2139 10.12.24 20:07 Сейчас в теме
Это действительно очень интересная ситуация, когда какой-то сервис шлет хтонические данные из HTML формы на сервер через formdata, при этом шлет на сервер не на свой, а на ваш :D
Оставьте свое сообщение