В процессе разработки интеграций в среде 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда один и тот же код для отправки HTTP-запросов идеально работает в тонком клиенте, но выдает критическую ошибку «Ошибка установки соединения» при запуске через веб-клиент (в браузере). Особенно это актуально при работе с современными API, такими как СберМаркет, где требуется использование защищенного соединения и специфических заголовков.
В данной статье мы подробно разберем, почему возникают такие сложности, проанализируем ограничения браузерной среды и рассмотрим наиболее правильные архитектурные решения для реализации POST запросов.
Прежде чем переходить к коду, давайте выясним причину такого поведения платформы. Основное различие заключается в среде выполнения:
Same Origin Policy. Если ваша база 1С опубликована на одном домене, а запрос вы отправляете на другой (например, sbermarket.ru), браузер заблокирует такой запрос, если удаленный сервер явно не разрешил это в своих заголовках. Тонкий клиент не является браузером и игнорирует эти ограничения.ЗащищенноеСоединениеOpenSSL фактически игнорируется. Браузер сам решает, доверяет ли он сертификату удаленного узла, основываясь на системном хранилище сертификатов операционной системы.Асинх в веб-клиенте часто приводит к ошибкам выполнения.Проанализируем наиболее надежный способ решения проблемы. Самый простой и эффективный путь — полностью отказаться от выполнения HTTP-запросов непосредственно из веб-клиента и передать эту задачу серверу 1С. Сервер не ограничен политиками браузера, корректно обрабатывает ЗащищенноеСоединениеOpenSSL и позволяет использовать привычные синхронные методы.
Рассмотрим пример реализации. Сначала создадим экспортную процедуру на сервере, которая будет принимать данные и возвращать результат:
&НаСервере
Функция ОтправитьДанныеНаСервер(Знач ТелоЗапросаСтрокой)
// 1. Настраиваем защищенное соединение
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
// 2. Создаем HTTP-соединение
// Обратите внимание: на сервере мы используем обычное синхронное создание
Соединение = Новый HTTPСоединение("retailers-gw.sbermarket.ru",,,,, 60, ЗащищенноеСоединение);
// 3. Формируем запрос
Запрос = Новый HTTPЗапрос("/ofm/api/v1/notifications");
Запрос.Заголовки.Вставить("Content-Type", "application/json");
Запрос.Заголовки.Вставить("Client-Token", "ВАШ_ТОКЕН");
Запрос.Заголовки.Вставить("Api-Version", "3.0");
// Устанавливаем тело запроса
Запрос.УстановитьТелоИзСтроки(ТелоЗапросаСтрокой, КодировкаТекста.UTF8);
Попытка
// 4. Отправляем запрос синхронным методом
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Возврат Ответ.ПолучитьТелоКакСтроку();
Исключение
ИнформацияОбОшибке = ИнформацияОбОшибке();
ЗаписьЖурналаРегистрации("HTTP_POST", УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке));
Возврат "Ошибка: " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке);
КонецПопытки;
КонецФункции
Теперь на клиенте (в веб-клиенте) нам достаточно просто вызвать эту функцию:
&НаКлиенте
Процедура ВыполнитьОтправку(Команда)
ДанныеДляОтправки = "{""status"": ""delivered""}"; // Пример JSON
Результат = ОтправитьДанныеНаСервер(ДанныеДляОтправки);
Сообщить(Результат);
КонецПроцедуры
Если по каким-то причинам вам необходимо выполнить запрос именно на стороне клиента (например, в мобильном приложении без постоянной связи с сервером), необходимо использовать асинхронную модель программирования. Начиная с версии платформы 8.3.18, для этого используются методы с суффиксом Асинх и ключевое слово Ждать.
Посмотрим на пример кода, который корректно работает с асинхронностью:
&НаКлиенте
Асинх Процедура ОтправитьДанныеАсинхронно()
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
// Создание соединения также может быть асинхронным в некоторых сценариях,
// но обычно достаточно асинхронной отправки
Соединение = Новый HTTPСоединение("retailers-gw.sbermarket.ru",,,,,, ЗащищенноеСоединение);
ЗапросОтправки = Новый HTTPЗапрос("/ofm/api/v1/notifications");
// Важно: Сначала заполняем заголовки, затем тело
ЗапросОтправки.Заголовки.Вставить("Content-Type", "application/json");
ЗапросОтправки.Заголовки.Вставить("Client-Token", "***");
ЗапросОтправки.УстановитьТелоИзСтроки(СтрокаJSON);
Попытка
// Используем Ждать для получения результата обещания
Результат = Ждать Соединение.ОтправитьДляОбработкиАсинх(ЗапросОтправки);
Если Результат.КодСостояния = 200 Тогда
Сообщить("Успешно отправлено");
Иначе
Сообщить("Код ошибки: " + Результат.КодСостояния);
КонецЕсли;
Исключение
Сообщить("Произошла сетевая ошибка при асинхронном вызове");
КонецПопытки;
КонецПроцедуры
Многие разработчики на платформе 8.3.21 и выше замечают, что метод ОтправитьДляОбработки исчезает из синтакс-помощника. Это происходит из-за того, что фирма «1С» объявила ряд методов HTTPСоединение устаревшими для клиентского использования.
Чтобы вернуть их отображение, выполните следующие шаги:
После этого в дереве справки снова появятся методы Записать, Получить, Удалить и ОтправитьДляОбработки. Однако помните, что на стороне клиента их использовать не стоит — лучше заменить их на ВызватьHTTPМетодАсинх(). Этот метод является универсальным и принимает имя метода (например, "POST") в качестве первого параметра.
Если вы все же решили использовать веб-клиент и получаете «Ошибку установки соединения», не полагайтесь только на сообщения 1С. Платформа часто маскирует детальные технические причины. Проанализируем ситуацию как веб-разработчики:
ERR_CERT_AUTHORITY_INVALID), либо блокировка CORS (CORS policy: No 'Access-Control-Allow-Origin' header is present).Важный совет: Если вы видите ошибку CORS, исправить её на стороне 1С невозможно. Вам придется либо просить владельцев API добавить ваш домен в список разрешенных, либо использовать предложенное выше Решение №1 (перенос на сервер), которое полностью обходит эту проблему.
Подводя итог, можно сказать, что выполнение HTTP-запросов из веб-клиента — это трудоемкий процесс, сопряженный с ограничениями безопасности современных браузеров. Для стабильной работы корпоративных систем мы рекомендуем придерживаться правила: сетевое взаимодействие должно происходить на сервере. Это гарантирует предсказуемость кода, легкость отладки и отсутствие проблем с сертификатами и кросс-доменными запросами.