Интеграция 1С со сторонними веб-приложениями, облачными сервисами и внешними API — одна из самых частых задач современного разработчика. В рамках данной статьи мы подробно разберем, может ли система 1С выступать в роли HTTP-клиента, какие механизмы для этого предоставляет платформа, и как правильно реализовать отправку запросов и обработку ответов с учетом лучших практик разработки.
Для того чтобы отправить запрос к стороннему серверу, нам понадобятся два ключевых объекта платформы 1С:Предприятие:
Рассмотрим простейший шаблон отправки GET-запроса на сервер. Для этого разберем по шагам следующий пример кода:
// Шаг 1. Создаем объект HTTP-соединения
АдресСервера = "api.example.com";
Соединение = Новый HTTPСоединение(АдресСервера);
// Шаг 2. Создаем HTTP-запрос с указанием пути к ресурсу
АдресРесурса = "/v1/data?param=value";
Запрос = Новый HTTPЗапрос(АдресРесурса);
// Шаг 3. Отправляем запрос и получаем ответ
Попытка
Ответ = Соединение.Получить(Запрос);
КодСостояния = Ответ.КодСостояния;
Если КодСостояния = 200 Тогда
ТекстОтвета = Ответ.ПолучитьТелоКакСтроку();
// Обработка полученных данных
Иначе
ВызватьИсключение "Ошибка сервера. Код состояния: " + КодСостояния;
КонецЕсли;
Исключение
// Обработка сетевых ошибок
ЗаписатьЛогОшибки(ОписаниеОшибки());
КонецПопытки;
При разработке интеграций крайне важно учитывать, где именно выполняется код — на сервере 1С или на стороне клиента. Начиная с версии платформы 1С:Предприятие 8.3.21, возможности работы с HTTP-запросами были значительно расширены, что важно учитывать для стабильности приложения.
Выясним разницу между подходами:
1. Синхронные методы на сервере
Если код выполняется в серверном модуле (например, в фоновом задании, в обработчике проведения документа или внутри вашего собственного HTTP-сервиса), мы используем классические синхронные методы, такие как Получить(), ОтправитьДляОбработки(), Записать(). В этом контексте выполнение серверного потока приостанавливается до тех пор, пока удаленный веб-сервис не вернет ответ или не сработает таймаут.
2. Асинхронные методы на клиенте
Если отправка запроса инициируется непосредственно из формы пользователем на клиенте (особенно в веб-клиенте), использование синхронных вызовов недопустимо и приведет к ошибке выполнения. В браузере синхронная блокировка потока интерфейса запрещена. Для этого в платформе реализованы асинхронные аналоги методов:
ПолучитьАсинх()ОтправитьДляОбработкиАсинх()ЗаписатьАсинх()Проанализируем пример асинхронного вызова на клиенте с использованием механизма обещаний:
&НаКлиенте
Асинх Процедура ПолучитьДанныеАсинхронно()
Соединение = Новый HTTPСоединение("api.example.com");
Запрос = Новый HTTPЗапрос("/v1/status");
Попытка
Ответ = Ждать Соединение.ПолучитьАсинх(Запрос);
Если Ответ.КодСостояния = 200 Тогда
ТекстРесурса = Ждать Ответ.ПолучитьТелоКакСтрокуАсинх();
ПоказатьПредупреждение(, "Данные получены: " + ТекстРесурса);
КонецЕсли;
Исключение
ПоказатьПредупреждение(, "Ошибка сети: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Подавляющее большинство современных веб-ресурсов используют протокол HTTPS для шифрования трафика. Если вы попытаетесь подключиться к такому серверу без явного указания защищенного соединения, платформа выдаст ошибку.
Для успешной отправки запросов по протоколу HTTPS необходимо передать специальный объект ЗащищенноеСоединениеOpenSSL в конструктор HTTPСоединения. Рассмотрим пример правильной инициализации:
// Инициализация защищенного соединения с дефолтными настройками ОС
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение("secure-api.com", 443, , , , , ЗащищенноеСоединение);
Обратите внимание на важные особенности проверки сертификатов, начиная с платформы версии 8.3.10:
// Отключение проверки сертификата сервера (только для тестирования!)
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Неопределено);
Современный стандарт де-факто для REST API — это формат JSON. Для того чтобы успешно передавать сложные структуры данных из 1С во внешние системы, нам нужно сериализовать объекты 1С (такие как Соответствие, Структура или Массив) в строку JSON, а при получении ответа — проводить обратную десериализацию.
Рассмотрим по шагам, как подготовить и отправить POST-запрос с JSON-телом:
// 1. Создаем структуру с данными для отправки
ДанныеЗапроса = Новый Структура;
ДанныеЗапроса.Вставить("clientId", "1С-Клиент-001");
ДанныеЗапроса.Вставить("status", "Active");
ДанныеЗапроса.Вставить("amount", 15200.50);
// 2. Сериализуем структуру в JSON-строку
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ДанныеЗапроса);
СтрокаJSON = ЗаписьJSON.Закрыть();
// 3. Формируем HTTP-запрос
Запрос = Новый HTTPЗапрос("/api/v1/update");
// Указываем заголовки, сообщающие серверу о формате передаваемых данных
Запрос.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
Запрос.УстановитьТелоИзСтроки(СтрокаJSON, КодировкаТекста.UTF8);
// 4. Отправляем данные
Соединение = Новый HTTPСоединение("api.example.com", , , , , , Новый ЗащищенноеСоединениеOpenSSL());
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Теперь разберем, как правильно обрабатывать ответ, полученный от сервера в формате JSON:
Если Ответ.КодСостояния = 200 Тогда
// Получаем строку ответа
СтрокаОтвета = Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
// Читаем JSON в структуру 1С
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(СтрокаОтвета);
РезультатДесериализации = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
// Теперь мы можем обращаться к свойствам как к ключам структуры
Если ТипЗнч(РезультатДесериализации) = Тип("Структура") Тогда
Успешно = РезультатДесериализации.status;
КонецЕсли;
КонецЕсли;
Распространенной ошибкой начинающих разработчиков является вера в то, что блок Попытка ... Исключение полностью защищает их от сбоев интеграции. Это не так. Конструкция обработки исключений перехватывает исключительно системные и сетевые сбои (проблемы с DNS, физическое отсутствие интернета, блокировка порта брандмауэром или истечение таймаута ожидания).
Если удаленный сервер успешно принял ваш запрос, обработал его, но вернул ошибку авторизации (код 401) или сообщил об ошибке в параметрах запроса (код 400), с точки зрения платформы 1С транзакция завершилась успешно. Исключение выброшено не будет!
Поэтому в обязательном порядке необходимо анализировать код ответа сервера:
Location и отправить повторный запрос по новому адресу.Одним из самых критических параметров при инициализации HTTPСоединения является Таймаут. Он задается в секундах и определяет, сколько времени 1С будет ожидать отклика от удаленного веб-сервиса до принудительного разрыва соединения.
Если этот параметр не задан, то в случае зависания внешнего веб-сервиса, поток выполнения 1С может оставаться заблокированным на неопределенный срок. Если интеграция вызывается из вашего собственного HTTP-сервиса 1С, то зависшие сессии займут все доступные рабочие процессы сервера приложений, что приведет к отказу в обслуживании для всех пользователей системы.
Рассмотрим, как правильно установить оптимальный таймаут:
// Задаем лимит ожидания в 15 секунд
ОжиданиеСекунд = 15;
Соединение = Новый HTTPСоединение("slow-api.com", , , , , ОжиданиеСекунд, Новый ЗащищенноеСоединениеOpenSSL());
Оптимальное время таймаута зависит от специфики внешнего сервиса. Для простых и быстрых REST API обычно достаточно 10–15 секунд. Если же вызываемый метод запускает на внешней стороне сложный расчет или генерацию тяжелых отчетов, таймаут следует увеличить до 60–120 секунд, а выполнение такой интеграции перевести в асинхронный фоновый режим.