При изучении примеров интеграции 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);
Чтобы привести данный код к современному виду, выполним следующие действия:
HTTPЗапрос, передав в его конструктор относительный путь ресурса и заголовки запроса в виде объекта Соответствие.УстановитьИмяФайлаТела.ОтправитьДляОбработки объекта HTTPСоединение, передав подготовленный запрос и путь к файлу для сохранения ответа.Посмотрим на пример обновленного кода:
// Создаем заголовки, если они еще не сформированы
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");
// Инициализируем соединение
HTTP = Новый HTTPСоединение("server.example.com", , , , ПроксиСервер);
// Формируем запрос
Запрос = Новый HTTPЗапрос("/upload.php", Заголовки);
Запрос.УстановитьИмяФайлаТела(ИмяФайлаHTML);
// Отправляем запрос и сохраняем ответ в файл
ИмяВыходногоФайла = КаталогВременныхФайлов() + "result.htm";
Ответ = HTTP.ОтправитьДляОбработки(Запрос, ИмяВыходногоФайла);
Важнейшее преимущество современной объектной модели заключается в том, что нам больше не требуется постоянно создавать временные файлы на диске. Это значительно ускоряет работу обменов и снижает нагрузку на дисковую подсистему сервера.
Выясним, какие методы доступны для работы с телом запроса в оперативной памяти:
Запрос.УстановитьТелоИзСтроки(<Строка>, <Кодировка>, <ИспользованиеBOM>) — подходит для отправки текстовых форматов (JSON, XML, URL-encoded строки).Запрос.УстановитьТелоИзДвоичныхДанных(<ДвоичныеДанные>) — применяется для передачи произвольных файлов и бинарных данных.Запрос.УстановитьТелоКакПоток(<Поток>) — используется для потоковой передачи больших объемов информации.Точно так же второй параметр в методе ОтправитьДляОбработки является необязательным. Если его опустить, ответ вернется в виде объекта 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Ответ:
Ответ.ПолучитьТелоКакСтроку(<Кодировка>);Ответ.ПолучитьТелоКакДвоичныеДанные();Ответ.ПолучитьТелоКакПоток().Обратите внимание на важный нюанс: метод ОтправитьДляОбработки не выбрасывает исключение при получении кодов ошибок от веб-сервера (семейства 4xx и 5xx, например 400 Bad Request, 404 Not Found или 500 Internal Server Error). В таких случаях метод успешно возвращает объект HTTPОтвет.
Конструкция Попытка ... Исключение перехватывает исключительно системные и сетевые сбои: отсутствие подключения к интернету, ошибки разрешения имени DNS, превышение таймаута ожидания или несовместимость настроек шифрования.
Посмотрим, как правильно организовать обработку результата:
Попытка
Ответ = HTTP.ОтправитьДляОбработки(Запрос);
Исключение
ИнформацияОбОшибке = ОписаниеОшибки();
// Обработка сетевой недоступности сервера или ошибки таймаута
ВызватьИсключение "Ошибка сетевого соединения: " + ИнформацияОбОшибке;
КонецПопытки;
// Проверка ответа самого веб-сервиса
Если Ответ.КодСостояния = 200 ИЛИ Ответ.КодСостояния = 201 Тогда
РезультатСтрокой = Ответ.ПолучитьТелоКакСтроку();
Иначе
ТекстОшибкиСервера = Ответ.ПолучитьТелоКакСтроку();
// Обработка логической ошибки API
КонецЕсли;
Помните, что метод ОтправитьДляОбработки жестко зафиксирован за протокольным методом POST. Если веб-сервис требует использования других методов, применяются соответствующие функции объекта HTTPСоединение:
Получить — выполняет запрос GET;Записать — выполняет запрос PUT;Удалить — выполняет запрос DELETE;Изменить — выполняет запрос PATCH;ВызватьHTTPМетод — универсальный метод, позволяющий указать любое имя HTTP-метода произвольной строкой (например, OPTIONS или HEAD).Важное замечание по безопасности: при работе с защищенным протоколом HTTPS (порт 443) недостаточно просто указать порт 443 в конструкторе HTTPСоединение. Обязательно передавайте в соответствующий параметр конструктора объект ЗащищенноеСоединениеOpenSSL, иначе 1С выполнит попытку подключения по незащищенному протоколу HTTP.