Почему в методе HTTPСоединение.ОтправитьДляОбработки различается количество параметров и как правильно отправлять запрос?

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

При изучении примеров интеграции 1С с внешними веб-сервисами часто возникает путаница: в старых статьях и обработках можно встретить вызов метода ОтправитьДляОбработки с четырьмя параметрами, тогда как синтакс-помощник актуальных версий платформы содержит только два параметра. Разберем причины этих различий, выясним, как развивалась модель работы с HTTP в 1С, и рассмотрим современные стандарты отправки POST-запросов.

Причина различий в синтаксисе метода

Проанализируем, почему возникает расхождение. В ранних версиях платформы (начиная с 1С:Предприятия 8.0 и до версии 8.3.4) вызов метода выглядел следующим образом:

HTTP.ОтправитьДляОбработки(<ИмяВходногоФайла>, <URI>, <ИмяВыходногоФайла>, <Заголовки>)

В этом устаревшем варианте все параметры передавались напрямую в метод объекта HTTPСоединение, а тело запроса и тело ответа могли передаваться исключительно через физические файлы на диске.

Начиная с версии 8.3.4, разработчики платформы полностью переработали архитектуру взаимодействия по протоколу HTTP. Логику разделили между специализированными объектами: HTTPСоединение, HTTPЗапрос и HTTPОтвет. Прежний синтаксис с четырьмя параметрами был оставлен исключительно для обратной совместимости, а основным стал метод с двумя параметрами:

HTTP.ОтправитьДляОбработки(<HTTPЗапрос>, <ИмяВыходногоФайла>)

Как перевести старый код на современный синтаксис

Рассмотрим по шагам, как переписать вызов с четырьмя параметрами на актуальный стандарт платформы 1С:Предприятие 8.3.

Предположим, что в старом коде использовалась следующая конструкция:


// Устаревшая реализация
HTTP = Новый HTTPСоединение("server.example.com", , , , ПроксиСервер);
HTTP.ОтправитьДляОбработки(ИмяФайлаHTML, "/upload.php", КаталогВременныхФайлов() + "result.htm", ЗаголовокHTTP);

Чтобы привести данный код к современному виду, выполним следующие действия:

  1. Создадим объект HTTPЗапрос, передав в его конструктор относительный путь ресурса и заголовки запроса в виде объекта Соответствие.
  2. Укажем файл тела запроса с помощью специального метода УстановитьИмяФайлаТела.
  3. Вызовем метод ОтправитьДляОбработки объекта HTTPСоединение, передав подготовленный запрос и путь к файлу для сохранения ответа.

Посмотрим на пример обновленного кода:


// Создаем заголовки, если они еще не сформированы
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");

// Инициализируем соединение
HTTP = Новый HTTPСоединение("server.example.com", , , , ПроксиСервер);

// Формируем запрос
Запрос = Новый HTTPЗапрос("/upload.php", Заголовки);
Запрос.УстановитьИмяФайлаТела(ИмяФайлаHTML);

// Отправляем запрос и сохраняем ответ в файл
ИмяВыходногоФайла = КаталогВременныхФайлов() + "result.htm";
Ответ = HTTP.ОтправитьДляОбработки(Запрос, ИмяВыходногоФайла);

Работа с телом запроса и ответом без временных файлов

Важнейшее преимущество современной объектной модели заключается в том, что нам больше не требуется постоянно создавать временные файлы на диске. Это значительно ускоряет работу обменов и снижает нагрузку на дисковую подсистему сервера.

Выясним, какие методы доступны для работы с телом запроса в оперативной памяти:

  1. Запрос.УстановитьТелоИзСтроки(<Строка>, <Кодировка>, <ИспользованиеBOM>) — подходит для отправки текстовых форматов (JSON, XML, URL-encoded строки).
  2. Запрос.УстановитьТелоИзДвоичныхДанных(<ДвоичныеДанные>) — применяется для передачи произвольных файлов и бинарных данных.
  3. Запрос.УстановитьТелоКакПоток(<Поток>) — используется для потоковой передачи больших объемов информации.

Точно так же второй параметр в методе ОтправитьДляОбработки является необязательным. Если его опустить, ответ вернется в виде объекта HTTPОтвет, данные из которого можно получить напрямую:


HTTP = Новый HTTPСоединение("server.example.com");

Запрос = Новый HTTPЗапрос("/api/data");
Запрос.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
Запрос.УстановитьТелоИзСтроки("{""action"": ""ping""}", КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

// Выполняем POST-запрос полностью в оперативной памяти
Ответ = HTTP.ОтправитьДляОбработки(Запрос);

Если Ответ.КодСостояния = 200 Тогда
    СтрокаОтвета = Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
КонецЕсли;

Для чтения ответа доступны следующие методы объекта HTTPОтвет:

  1. Ответ.ПолучитьТелоКакСтроку(<Кодировка>);
  2. Ответ.ПолучитьТелоКакДвоичныеДанные();
  3. Ответ.ПолучитьТелоКакПоток().

Особенности обработки ошибок при выполнении HTTP-запросов

Обратите внимание на важный нюанс: метод ОтправитьДляОбработки не выбрасывает исключение при получении кодов ошибок от веб-сервера (семейства 4xx и 5xx, например 400 Bad Request, 404 Not Found или 500 Internal Server Error). В таких случаях метод успешно возвращает объект HTTPОтвет.

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

Посмотрим, как правильно организовать обработку результата:


Попытка
    Ответ = HTTP.ОтправитьДляОбработки(Запрос);
Исключение
    ИнформацияОбОшибке = ОписаниеОшибки();
    // Обработка сетевой недоступности сервера или ошибки таймаута
    ВызватьИсключение "Ошибка сетевого соединения: " + ИнформацияОбОшибке;
КонецПопытки;

// Проверка ответа самого веб-сервиса
Если Ответ.КодСостояния = 200 ИЛИ Ответ.КодСостояния = 201 Тогда
    РезультатСтрокой = Ответ.ПолучитьТелоКакСтроку();
Иначе
    ТекстОшибкиСервера = Ответ.ПолучитьТелоКакСтроку();
    // Обработка логической ошибки API
КонецЕсли;

Методы HTTPСоединение и защищенное соединение

Помните, что метод ОтправитьДляОбработки жестко зафиксирован за протокольным методом POST. Если веб-сервис требует использования других методов, применяются соответствующие функции объекта HTTPСоединение:

  1. Получить — выполняет запрос GET;
  2. Записать — выполняет запрос PUT;
  3. Удалить — выполняет запрос DELETE;
  4. Изменить — выполняет запрос PATCH;
  5. ВызватьHTTPМетод — универсальный метод, позволяющий указать любое имя HTTP-метода произвольной строкой (например, OPTIONS или HEAD).

Важное замечание по безопасности: при работе с защищенным протоколом HTTPS (порт 443) недостаточно просто указать порт 443 в конструкторе HTTPСоединение. Обязательно передавайте в соответствующий параметр конструктора объект ЗащищенноеСоединениеOpenSSL, иначе 1С выполнит попытку подключения по незащищенному протоколу HTTP.

← На главную