Как разобрать параметры POST-запроса в HTTP-сервисе 1С 8.3

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке HTTP-сервисов в среде 1С:Предприятие 8.3 разработчики часто сталкиваются с ситуацией, когда при получении POST-запроса стандартное свойство ПараметрыЗапроса (тип ФиксированноеСоответствие) оказывается пустым. Это происходит потому, что платформа автоматически заполняет это свойство только параметрами, переданными в строке URL (после знака вопроса). Если же данные передаются в теле запроса (body) в формате application/x-www-form-urlencoded, нам необходимо разбирать их самостоятельно.

В данной статье мы подробно рассмотрим, как программно извлечь данные из тела запроса, превратить их в удобную структуру и корректно обработать вложенные данные, такие как XML-строки.

Почему ПараметрыЗапроса пустые?

Разберем ситуацию: сторонний сервис или сайт отправляет запрос на ваш HTTP-сервис. В заголовках указан метод POST, а тело запроса выглядит примерно так: xml_data=...&card=PT_EPOS&mer_no=ok22. Для платформы 1С это единый блок данных. Она не «парсит» его автоматически в коллекцию параметров, так как это данные тела, а не заголовка запроса. Чтобы работать с этими данными, мы должны сначала получить их как сырую строку, а затем применить алгоритм декомпозиции.

Шаг 1: Получение тела запроса

Первым делом в методе-обработчике (например, ЛюбойМетод(Запрос)) нам нужно извлечь содержимое. Рассмотрим, как это сделать правильно:


// Получаем тело запроса в виде строки
// Важно: если ожидаются кириллические символы, лучше явно указать кодировку
ТелоЗапроса = Запрос.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);

Если мы проанализируем переменную ТелоЗапроса, мы увидим длинную строку, где параметры разделены символом амперсанда (&), а ключи и значения разделены знаком равенства (=).

Шаг 2: Простой алгоритм разбора строки в структуру

Проанализируем самый быстрый и очевидный способ разделения строки. Мы воспользуемся встроенной функцией СтрРазделить, которая позволяет превратить строку в массив по разделителю.


// Разделяем строку на массив пар "ключ=значение"
МассивПараметров = СтрРазделить(ТелоЗапроса, "&");

// Создаем структуру для хранения результата
СтруктураРезультат = Новый Структура;

Для Каждого СтрокаПараметр Из МассивПараметров Цикл
    // Каждую пару разделяем по первому символу "="
    ПозицияРазделителя = СтрНайти(СтрокаПараметр, "=");
    
    Если ПозицияРазделителя > 0 Тогда
        Ключ = Лев(СтрокаПараметр, ПозицияРазделителя - 1);
        Значение = Сред(СтрокаПараметр, ПозицияРазделителя + 1);
        
        // Вставляем в структуру. 
        // Внимание: имя ключа должно соответствовать правилам имен в 1С!
        СтруктураРезультат.Вставить(Ключ, Значение);
    КонецЕсли;
КонецЦикла;

Шаг 3: Учет URL-кодирования (Percent-encoding)

Рассмотрим критически важный нюанс, который часто упускают. Данные в формате x-www-form-urlencoded передаются в закодированном виде. Например, вместо пробела будет символ + или %20, а вместо знаков < и > в XML — последовательности %3C и %3E. Если просто использовать СтрРазделить, ваш XML-текст будет испорчен и не прочитается стандартным средством ЧтениеXML.

Для решения этой проблемы мы должны использовать функцию РаскодироватьСтроку. Модернизируем наш алгоритм:


Функция РазобратьТелоЗапроса(Знач ТелоСтрокой) Экспорт
    Результат = Новый Соответствие; // Используем Соответствие, т.к. ключи могут быть любыми
    
    МассивПар = СтрРазделить(ТелоСтрокой, "&");
    
    Для Каждого Пара Из МассивПар Цикл
        Поз = СтрНайти(Пара, "=");
        Если Поз > 0 Тогда
            Ключ = Лев(Пара, Поз - 1);
            ЗначениеЗакодированное = Сред(Пара, Поз + 1);
            
            // Заменяем "+" на пробел, так как РаскодироватьСтроку может этого не сделать 
            // в зависимости от специфики отправителя
            ЗначениеЗакодированное = СтрЗаменить(ЗначениеЗакодированное, "+", " ");
            
            // Декодируем спецсимволы (URL Decode)
            Значение = РаскодироватьСтроку(ЗначениеЗакодированное, СпособКодированияСтроки.URLАнкор);
            
            Результат.Вставить(Ключ, Значение);
        КонецЕсли;
    КонецЦикла;
    
    Возврат Результат;
КонецФункции

Шаг 4: Обработка полученного XML

Выясним, как работать с параметром, который содержит XML-данные (в нашем примере это xml_data). После того как мы раскодировали строку и получили «чистый» XML, мы можем использовать стандартную фабрику XDTO для превращения текста в объект 1С.


// Предположим, Параметры - это Соответствие, полученное на предыдущем шаге
ТекстXML = Параметры.Получить("xml_data");

Если ТекстXML <> Неопределено Тогда
    ЧтениеXML = Новый ЧтениеXML;
    ЧтениеXML.УстановитьСтроку(ТекстXML);
    
    Попытка
        // Используем фабрику XDTO для чтения
        ОбъектДанных = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML);
        // Теперь в переменной ОбъектДанных находится объектная модель вашего XML
    Исключение
        ЗаписьЖурналаРегистрации("Ошибка разбора XML", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
    КонецПопытки;
КонецЕсли;

Важные рекомендации

Проанализируем несколько советов, которые помогут сделать интеграцию более надежной:

  1. Проверка Content-Type: Перед началом разбора убедитесь, что отправитель прислал данные именно в ожидаемом формате. Проверьте заголовок Запрос.Заголовки.Получить("Content-Type").
  2. Использование Соответствия вместо Структуры: Если ключи параметров содержат дефисы (например, notify-signature), метод Структура.Вставить() вызовет ошибку, так как имя свойства структуры не может содержать дефис. Соответствие лишено этого ограничения.
  3. Логирование: Всегда записывайте входящее тело запроса в Журнал Регистрации в режиме отладки. Это позволит вам увидеть реальную структуру данных, если разбор упадет с ошибкой.
  4. Обработка спецсимволов: Если внутри вашего XML могут встречаться символы & или = как часть текстовых данных, убедитесь, что отправляющая сторона корректно их экранирует, иначе простой СтрРазделить по этим символам «разрежет» ваш XML в непредсказуемых местах.

Таким образом, мы разобрали полный цикл обработки POST-запроса: от получения сырых данных из тела до восстановления структуры и парсинга XML. Использование функций СтрРазделить и РаскодироватьСтроку является надежным стандартом для обработки форм, отправляемых веб-сайтами в 1С.

← На главную