Подсистема 1С для работы с HTTP
Представляет собой библиотеку методов и инструменты выполнения HTTP-запросов. Реализованы:
- исполнение запросов по URI (Клиент "понимает" IDN)
- исполнять запросы можно на клиенте (асинхронно) и на сервере, а также в мобильном приложении 1С
- текучий интерфейс методов настройки выполнения запроса
- методы GET, POST, PUT, DELETE, HEAD, PATCH
- передача в теле запроса текста, данных файлов и двоичных данных
- хранение данных результатов запросов в рамках сессии (Cookie, перенаправления)
- получение сжатого контента в ответе
- консоль интерактивного выполнения запросов
- генерация кода 1С, интерактивно настроенного в Консоли запроса
- импорт файла Postman (формат файла v2.1)
- настройка Консоли в соответствии с командой консольной утилиты curl и генерация команды curl по настроенной Консоли
- повторение попыток выполнить запрос после неуспешного результата (retry) с настраиваемой задержкой (backoff)
Кредо системы: лаконичная результативность. К чему и стремимся.
Является open source с лицензией Apache 2.0
Пример кода
В первую очередь Клиент – это библиотека методов выполнения HTTP-запросов.
Версия 1 использует синхронные вызовы, поэтому при вызове функций выполнения запроса с клиента и с сервера тип ответа отличаться не будет.
В версии 2 вызовы с клиента асинхронные – функции выполнения запроса вернут Обещание.
Оформлял экспортные методы модулей с комментариями. Все методы выполнения представлены в модуле КлиентHTTPКлиентСервер. Константные значения – в КлиентHTTPПовтИсп. Пара примеров:
Просто GET
// Для версии 1, на сервере или для внешнего соединения
Ответ = КлиентHTTPКлиентСервер.Получить("https://ya.ru");
// На клиенте для версии 2
Ответ = Ждать КлиентHTTPКлиентСервер.Получить("https://ya.ru");
Установка параметров запроса
Адрес = "https://evilinsult.com/generate_insult.php";
// Добавим параметры URL: ?lang=ru&type=json
ПЗ = КлиентHTTPКлиентСервер.НовыеПараметрыЗапроса();
КлиентHTTPКлиентСервер
.ДобавитьПараметр(ПЗ, "lang", "ru")
.ДобавитьПараметр(ПЗ, "type", "json");
Ответ = КлиентHTTPКлиентСервер.Получить(Адрес, ПЗ); // на вызов с клиента в версии 2 вернётся Обещание
Текст = ПолучитьСтрокуИзДвоичныхДанных(Ответ.Тело);
или же
// Для версии 1, на сервере или для внешнего соединения
Ответ = КлиентHTTPКлиентСервер.Получить(
"https://evilinsult.com/generate_insult.php?lang=ru&type=json"
);
// На клиенте для версии 2
Ответ = Ждать КлиентHTTPКлиентСервер.Получить(
"https://evilinsult.com/generate_insult.php?lang=ru&type=json"
);
Сохранение тела ответа в файл
Адрес = "https://epic.gsfc.nasa.gov/archive/natural/2015/10/31/png/epic_1b_20151031074844.png";
ДП = КлиентHTTPКлиентСервер.НовыеДополнительныеПараметры();
Ответ = КлиентHTTPКлиентСервер
.УстановитьИмяВыходногоФайла(ДП, "С:\tmp\pic.png")
.Получить(Адрес, , ДП);
POST текста
Адрес = "https://jsonplaceholder.typicode.com/posts";
Данные = "{""title"": ""foo"", ""body"": ""bar"", ""userId"": 1}";
ДП = КлиентHTTPКлиентСервер.НовыеДополнительныеПараметры();
Ответ = КлиентHTTPКлиентСервер
.УстановитьТипMIME(ДП, КлиентHTTPПовтИсп.ТипMIMEJSON())
.УстановитьКодировку(ДП, КлиентHTTPПовтИсп.КодировкаUTF16())
.ОтправитьТекст(Адрес, Данные, ДП);
POST multipart/form-data
Адрес = "https://httpbin.org/post";
ПФ = КлиентHTTPКлиентСервер.НовыеПоляФормы();
ФайлПоля = Новый Файл("C:\temp\1.png");
Ответ = КлиентHTTPКлиентСервер
.ДобавитьПолеФормыФайл(ПФ, "my_file", ФайлПоля, ФайлПоля.Имя, КлиентHTTPСлужебный.ТипMIMEРасширенияФайла(ФайлПоля.Расширение))
.ДобавитьПолеФормыТекст(ПФ, "user_name", "Имярек")
.ОтправитьДанныеФормы(Адрес, ПФ);
POST application/x-www-form-urlencoded
Адрес = "https://httpbin.org/post";
ПФ = КлиентHTTPКлиентСервер.НовыеПоляФормы();
Ответ = КлиентHTTPКлиентСервер
.ДобавитьПолеHTMLФормы(ПФ, "user_name", "Имярек")
.ДобавитьПолеHTMLФормы(ПФ, "role", "Сотрудник")
.ОтправитьДанныеHTMLФормы(Адрес, ПФ);
Авторизация
ДП = КлиентHTTPКлиентСервер.НовыеДополнительныеПараметры();
Ответ = КлиентHTTPКлиентСервер
.УстановитьDigestАвторизацию(ДП, "login", "password")
.Получить("http://192.168.1.1", , ДП);
Преобразование тела ответа
// Объект идентификатора ресурса соответствующий URI: https://evilinsult.com/generate_insult.php?lang=ru&type=json
оАдрес = КлиентHTTPКлиентСервер.ОбъектИдентификатораРесурса("evilinsult.com", , "generate_insult.php?lang=ru&type=json");
ПЗ = КлиентHTTPКлиентСервер.НовыеПараметрыЗапроса();
ДП = КлиентHTTPКлиентСервер.НовыеДополнительныеПараметры();
// В Ответ.Тело получаем структуру
Ответ = КлиентHTTPКлиентСервер
.ТелоОтветаКакJSON(ДП)
.Получить(оАдрес, ПЗ, ДП);
Переиспользование HTTP-соединения
ДП = КлиентHTTPКлиентСервер.НовыеДополнительныеПараметры();
КлиентHTTPКлиентСервер.ПереиспользоватьСоединение(ДП);
// Первый после включения режима переиспользования запрос сохранит объект HTTP-соединения
Ответ = КлиентHTTPКлиентСервер.Получить("https://ya.ru", , ДП);
Для я = 1 По 100 Цикл
ПЗ = КлиентHTTPКлиентСервер.НовыеПараметрыЗапроса();
Ответ = КлиентHTTPКлиентСервер
.ДобавитьПараметр(ПЗ, "nr", XMLСтрока(я))
.Получить("https://ya.ru/", ПЗ, ДП); // объект HTTP-соединения будет переиспользован
КонецЦикла;
При каждом вызове функции ПереиспользоватьСоединение
очищается сохранённый Объект HTTP-соединения. Проверка соответствия конфигурации соединения текущего запроса и сохранённого HTTP-соединения не осуществляется.
Повторные попытки выполнить запрос с задержкой
ДП = КлиентHTTPКлиентСервер.НовыеДополнительныеПараметры();
Ответ = Ждать КлиентHTTPКлиентСервер
.ЭкспоненциальноОтложенныеВыполнения(ДП, , , 3, 600)
.Получить("http://127.0.0.0", , ДП);
ВНИМАНИЕ! Неуспешный HTTP-запрос вызывает исключение, что помешает зафиксировать цепочку транзаций, в которой выполнялся запрос, даже если в итоге одна из попыток его выполнения будет успешной.
Использование сессии (включение Cookie и перенаправлений)
ДП = КлиентHTTPКлиентСервер.НовыеДополнительныеПараметры();
КлиентHTTPКлиентСервер.ИспользоватьСессию(ДП);
// На вызов функций выполнения запроса с клиента в версии 2 вернётся Обещание - имеет смысл Ждать
Ответ1 = КлиентHTTPКлиентСервер.Получить("https://www.google.com/search?q=infostart", , ДП);
Ответ2 = КлиентHTTPКлиентСервер.Получить("https://play.google.com/store/search?q=infostart", , ДП);
// КукиЗдесь = ДП.Сессия.Печенье;
// Перенаправления сработают автоматически
Стандартный стиль кода
Если текучий интерфейс вам не подходит:
Адрес = "https://evilinsult.com/generate_insult.php";
// Обернём длинное имя общего модуля в переменную
мКлиент = КлиентHTTPКлиентСервер;
ПЗ = мКлиент.НовыеПараметрыЗапроса();
ДП = мКлиент.НовыеДополнительныеПараметры();
мКлиент.ДобавитьПараметр(ПЗ, "lang", "ru")
мКлиент.ДобавитьПараметр(ПЗ, "type", "json");
мКлиент.ТелоОтветаКакJSON(ДП);
Ответ = мКлиент.Получить(Адрес, ПЗ, ДП);
Консоль
Неосновная, но приятная фича Клиента – Консоль. Инструмент интерактивного выполнения запросов с кодогенерацией.
Обработка КлиентHTTP. Интерфейсом ориентировался на Postman. Сложностей по части UX (кроме багов) возникнуть не должно. В Консоли можно импортировать файл Postman или распарсить команду curl. Получается мощная связка:
- Импортируем (Postman или curl)
- Получаем код 1С
- PROFIT!
Так же можно сделать обратное – собрать запрос в Консоли и получить команду curl.
Результат выполнения запроса со статистикой выполнения
История выполненных запросов с возможностью экспорта/импорта
Окно редактирования Cookie с примером редактирования текста поля
Окно сгенерированного Консолью кода (версия 2)
Установка
Разрабатывается на платформе 8.3.21.1302
Тестировалось на платформе для мобильных устройств 8.3.18.77
Ограничения версии 2:
- Требуемая минимальная версия платформы 8.3.18
Ограничения версии 1:
- Требуемая минимальная версия платформы 8.3.10
- Используются синхронные вызовы
- Не для мобильной платформы
HTTP-клиент встраивается в целевую конфигурацию сравнением / объединением. Объединять по подсистеме файла "КлиентHTTP".
Для обычных форм:
- удостоверьтесь, что в свойствах конфигурации активна опция "Использовать управляемые формы в толстом клиенте и обычном режиме"
- для общих модулей КлиентHTTPКлиентСервер, КлиентHTTPПовтИсп и КлиентHTTPСлужебный в свойствах установите опцию "Клиент (обычное приложение)"
PS
С интересом приму помощь в развитии Клиента. Клонируйте репозиторий, создавайте issue, пушьте пул-реквесты, пишите комментарии и главное – пользуйтесь.
Бесплатно Клиент скачать можно тут. А если хотите выразить благодарность в виде SM – с радостью буду за них приобретать на Инфостарте разработки коллег.