При интеграции 1С с внешними веб-сервисами часто возникает задача повторить действия обычной HTML-формы программно. На первый взгляд это кажется простым, но дьявол кроется в деталях: способе передачи параметров, кодировке и структуре самого HTTP-пакета. Разберем подробно, как перенести рабочую HTML-форму в код 1С, проанализируем типичные ошибки и рассмотрим продвинутые приемы работы с протоколом HTTP.
Для начала проанализируем структуру стандартной HTML-формы, которую нам необходимо эмулировать. Рассмотрим пример:
<FORM ACTION="https://site.ru/charge/charge.cfm" METHOD="POST">
<INPUT TYPE="TEXT" NAME="BillNumber" VALUE="5113507224001229">
<INPUT TYPE="HIDDEN" NAME="Merchant_ID" VALUE="113507">
<INPUT TYPE="HIDDEN" NAME="Login" VALUE="demo_user">
<INPUT TYPE="HIDDEN" NAME="Password" VALUE="password123">
<INPUT TYPE="HIDDEN" NAME="Format" VALUE="3">
<INPUT TYPE="SUBMIT" NAME="Submit" VALUE="Confirm">
</FORM>
Здесь важно обратить внимание на три ключевых момента:
Часто программисты 1С пытаются передать данные формы через заголовки запроса (Headers), используя объект Соответствие. Рассмотрим, почему это приводит к ошибкам, таким как ERROR-150 или некорректным ответам сервера.
Когда мы заполняем заголовки методом ЗаголовокHTTP.Вставить("BillNumber", BillNumber), эти данные попадают в служебную часть HTTP-пакета. Однако веб-сервер, настроенный на обработку форм, ищет эти данные исключительно в теле запроса. В результате сервер получает пустой набор данных формы и возвращает логическую ошибку, хотя сам транспортный уровень может вернуть код 200 (ОК), так как запрос был доставлен успешно.
Выясним, как правильно сформировать запрос. Процесс можно разделить на подготовку строки параметров, настройку соединения и отправку.
Шаг 1. Формирование строки тела запроса
Данные формы должны быть представлены в формате application/x-www-form-urlencoded. Это строка вида Ключ1=Значение1&Ключ2=Значение2. Рассмотрим пример формирования такой строки:
ПараметрыЗапроса = "BillNumber=" + НомерСчета +
"&Merchant_ID=" + ИдентификаторМерчанта +
"&Login=" + Логин +
"&Password=" + Пароль +
"&Format=3" +
"&Submit=Confirm";
Важный нюанс: Если в ваших значениях могут встретиться спецсимволы (пробелы, знаки & или русские буквы), обязательно используйте функцию КодироватьСтроку с типом СпособКодированияСтроки.URLУмеренный.
Шаг 2. Настройка HTTP-соединения и запроса
Теперь соберем все воедино, используя объекты платформы 1С.
// Подготовка соединения
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
СтруктураURL = СтруктураURL(ПолныйАдрес); // Парсим адрес на хост и путь
HTTPСоединение = Новый HTTPСоединение(СтруктураURL.Хост, , , , , 60, ЗащищенноеСоединение);
// Формируем заголовки
Заголовки = Новый Соответствие();
Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");
// Создаем запрос
HTTPЗапрос = Новый HTTPЗапрос(СтруктураURL.ПутьНаСервере, Заголовки);
// Устанавливаем данные в ТЕЛО запроса
HTTPЗапрос.УстановитьТелоИзСтроки(ПараметрыЗапроса, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
// Отправляем и получаем результат
Попытка
Ответ = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
Если Ответ.КодСостояния = 200 Тогда
ТекстОтвета = Ответ.ПолучитьТелоКакСтроку();
// Обработка XML или JSON ответа
Иначе
Сообщить("Ошибка сервера: " + Ответ.КодСостояния);
КонецЕсли;
Исключение
Сообщить("Сетевая ошибка отправки!");
КонецПопытки;
Проанализируем тонкости, которые могут повлиять на результат интеграции:
1. Управление BOM (Byte Order Mark)
При вызове метода УстановитьТелоИзСтроки крайне важно указывать третий параметр ИспользованиеByteOrderMark.НеИспользовать. Многие веб-серверы (особенно старые реализации на PHP или ColdFusion) воспринимают метку BOM как посторонний мусор в начале запроса, из-за чего первый параметр (в нашем случае BillNumber) не распознается.
2. Аутентификация: Basic Auth vs Form Fields
В примере автора Login и Password передавались в конструктор HTTPСоединение. Это включает стандартную HTTP-аутентификацию (Basic Auth). Однако в HTML-форме это просто текстовые поля. Если сервер ожидает их в теле POST-запроса, то передача их в конструкторе соединения будет бесполезна или даже вредна. Всегда проверяйте, являются ли логин/пароль частью данных формы или заголовками авторизации.
3. Эмуляция нажатия кнопки Submit
Обратите внимание на поле <INPUT TYPE="SUBMIT" NAME="Submit" VALUE="Confirm">. Иногда серверные скрипты проверяют наличие именно этого ключа в запросе, чтобы подтвердить, что форма была отправлена человеком через браузер. Рекомендуется всегда добавлять &Submit=Confirm в строку параметров 1С.
В некоторых случаях (например, при работе в старых версиях платформы или специфических требованиях к TLS) разработчики используют COM-объект WinHttp.WinHttpRequest.5.1. Посмотрим, как выглядит аналогичный запрос через этот механизм:
WinHttp = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
WinHttp.Open("POST", "https://site.ru/charge/charge.cfm", Ложь);
WinHttp.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded");
ДанныеДляОтправки = "BillNumber=5113507224001229&Merchant_ID=113507&Submit=Confirm";
// В WinHttp данные передаются непосредственно в метод Send
WinHttp.Send(ДанныеДляОтправки);
Если WinHttp.Status = 200 Тогда
ТекстОтвета = WinHttp.ResponseText;
КонецЕсли;
Этот метод более лаконичен, но менее гибок в плане кроссплатформенности, так как работает только в среде Windows.
Мы выяснили, что для успешной конвертации HTML-запроса в 1С недостаточно просто перечислить параметры. Ключевым фактором является понимание того, где эти параметры должны находиться. Заголовки используются для метаданных (тип контента, авторизация), а тело запроса — для самих данных формы. Правильное использование УстановитьТелоИзСтроки, контроль кодировок и отключение BOM гарантируют стабильную работу ваших интеграций.