Декодирование 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С:Предприятие 8 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) в договоре. Группирует задолженность по интервалам. Имеет большое количество настроек. Доступен API для использования рассчитанной задолженности в других отчетах, обработках, рабочих местах и т.п. Не требует доработок конфигурации. Не требует перепроведения документов.

16680 руб.

28.09.2012    103769    597    301    

154

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

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

6480 руб.

23.12.2021    15589    29    25    

12

Загрузка и выгрузка в Excel Универсальные функции Программист 1С:Предприятие 8 Россия Бесплатно (free)

Описанный ниже подход позволяет в три шага заполнять формулы в Excel файлы, вне зависимости от ОС сервера (MS Windows Server или Linux). Подход подразумевает отказ от работы с COM-объектом в пользу работы через "объектную модель документа" (DOM).

30.10.2025    3318    Abysswalker    7    

44

Универсальные функции Работа с интерфейсом Программист 1С:Предприятие 8 Бесплатно (free)

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

14.05.2025    6169    DeerCven    15    

57

Универсальные функции Программист 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

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

21.05.2024    48208    dimanich70    83    

169

Универсальные функции Программист 1С:Предприятие 8 1C:Бухгалтерия Абонемент ($m)

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

1 стартмани

18.03.2024    7257    6    John_d    13    

59

Универсальные функции Программист Стажер 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

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

12.02.2024    60143    atdonya    31    

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

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


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

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


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

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


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

0 - "0"
1 - "value"

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

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

Для Каждого Операнд Из МассивЗначений Цикл
	
	ПодстрокаЗамены = РаботаСФормуламиКлиентСервер.ПолучитьТекстОперандаДляВставки(Операнд);
	ИмяПараметра 	= СтрЗаменить(ИмяПараметра, ПодстрокаЗамены, "");
	
КонецЦикла;
Показать
3. bme 245 11.12.24 06:44 Сейчас в теме
(1) Да, так тоже можно собрать массив свойств, спасибо за подсказку!
2. bayselonarrend 3002 10.12.24 20:07 Сейчас в теме
Это действительно очень интересная ситуация, когда какой-то сервис шлет хтонические данные из HTML формы на сервер через formdata, при этом шлет на сервер не на свой, а на ваш :D
4. user1999272 19.06.25 17:31 Сейчас в теме
Как-то громоздко. У меня так было, без регулярок и БСП:
Для Каждого ПараметрИЗначение Из ПараметрыИЗначения Цикл   
		мПар = СтрРазделить(СтрЗаменить(ПараметрИЗначение, "]", ""), "=");
		Имена= СтрРазделить(мПар[0],"["); 
		папа=Результат;
		Для Индекс = 0 По Имена.ВГраница() Цикл
			Если ЭтоЧисло(Имена[Индекс])И ТипЗнч(папа) = Тип("Массив") Тогда
				Индекс_м=Число(Имена[Индекс]);
				Если Индекс_м > папа.ВГраница() Тогда
					папа.Добавить();
				КонецЕсли;
				Если папа.Получить(Индекс_м)=Неопределено Тогда
					вложенный=Новый Соответствие();
					папа.Установить(Индекс_м,вложенный); 
					папа=вложенный;
				иначе
					папа=папа.Получить(Индекс_м);
				КонецЕсли;
			Иначе
				СущЗначениеПараметра = папа.Получить(Имена[Индекс]);
				Если СущЗначениеПараметра = Неопределено Тогда
					Если Индекс=Имена.ВГраница() Тогда
						папа.Вставить(Имена[Индекс],мПар[1]);    
					иначеЕсли ЭтоЧисло(Имена[Индекс+1]) Тогда
						вложенный=Новый Массив;  
						папа.Вставить(Имена[Индекс],вложенный);
						папа=вложенный;
					иначе						
						вложенный=Новый Соответствие();
						папа.Вставить(Имена[Индекс],вложенный);
						папа=вложенный;
					КонецЕсли;					
				иначе
					папа=СущЗначениеПараметра;
				КонецЕсли;	
			КонецЕсли; 
		КонецЦикла;
	КонецЦикла; 
Показать

Как раз для этих самых custom_fields[0][name]=а0&custom_fields[0][value]=b0&custom_fields[1][name]=а1&custom_fields[1][value]=b1
5. aleksey2 91 22.10.25 08:05 Сейчас в теме
А существует обратное преобразование?
Из структуры в длинную строку.
Для отправки сообщения требуется регистрация/авторизация