Как настроить 1С для работы в качестве HTTP-клиента и запрашивать данные у сторонних серверов?

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

Интеграция 1С со сторонними веб-приложениями, облачными сервисами и внешними API — одна из самых частых задач современного разработчика. В рамках данной статьи мы подробно разберем, может ли система 1С выступать в роли HTTP-клиента, какие механизмы для этого предоставляет платформа, и как правильно реализовать отправку запросов и обработку ответов с учетом лучших практик разработки.

Основные объекты для работы с HTTP-запросами в 1С

Для того чтобы отправить запрос к стороннему серверу, нам понадобятся два ключевых объекта платформы 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 для шифрования трафика. Если вы попытаетесь подключиться к такому серверу без явного указания защищенного соединения, платформа выдаст ошибку.

Для успешной отправки запросов по протоколу HTTPS необходимо передать специальный объект ЗащищенноеСоединениеOpenSSL в конструктор HTTPСоединения. Рассмотрим пример правильной инициализации:


// Инициализация защищенного соединения с дефолтными настройками ОС
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение("secure-api.com", 443, , , , , ЗащищенноеСоединение);

Обратите внимание на важные особенности проверки сертификатов, начиная с платформы версии 8.3.10:

  1. Если сторонний сервер использует самоподписанный SSL-сертификат или цепочка сертификатов не является доверенной в операционной системе, 1С заблокирует соединение с ошибкой «Удаленный узел не прошел проверку».
  2. Для решения этой проблемы необходимо либо импортировать корневой сертификат веб-сервиса в хранилище доверенных сертификатов операционной системы на сервере 1С:Предприятия, либо прописать его в файл cacert.pem, поставляемый вместе с платформой 1С.
  3. Если безопасность соединения в тестовой среде не критична, можно инициализировать объект с отключенной проверкой подлинности сервера (хотя крайне не рекомендуется делать это на продуктовых базах):

// Отключение проверки сертификата сервера (только для тестирования!)
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Неопределено);

Форматирование данных и обмен в формате JSON

Современный стандарт де-факто для 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;
    КонецЕсли;
КонецЕсли;

Обработка ошибок и кодов состояния HTTP

Распространенной ошибкой начинающих разработчиков является вера в то, что блок Попытка ... Исключение полностью защищает их от сбоев интеграции. Это не так. Конструкция обработки исключений перехватывает исключительно системные и сетевые сбои (проблемы с DNS, физическое отсутствие интернета, блокировка порта брандмауэром или истечение таймаута ожидания).

Если удаленный сервер успешно принял ваш запрос, обработал его, но вернул ошибку авторизации (код 401) или сообщил об ошибке в параметрах запроса (код 400), с точки зрения платформы 1С транзакция завершилась успешно. Исключение выброшено не будет!

Поэтому в обязательном порядке необходимо анализировать код ответа сервера:

Использование таймаутов для предотвращения зависания системы

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

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

Рассмотрим, как правильно установить оптимальный таймаут:


// Задаем лимит ожидания в 15 секунд
ОжиданиеСекунд = 15;
Соединение = Новый HTTPСоединение("slow-api.com", , , , , ОжиданиеСекунд, Новый ЗащищенноеСоединениеOpenSSL());

Оптимальное время таймаута зависит от специфики внешнего сервиса. Для простых и быстрых REST API обычно достаточно 10–15 секунд. Если же вызываемый метод запускает на внешней стороне сложный расчет или генерацию тяжелых отчетов, таймаут следует увеличить до 60–120 секунд, а выполнение такой интеграции перевести в асинхронный фоновый режим.

← На главную