Как добавить отбор по дате в HTTP GET-запрос к сайту из 1С

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

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

Принцип передачи параметров в протоколе HTTP

Протокол HTTP в методе GET не предусматривает отправку тела сообщения (payload). Все параметры фильтрации, пагинации (постраничной навигации) и сортировки передаются непосредственно в строке адреса ресурса (Query String). Проанализируем базовые правила формирования такой строки:

  1. Адрес ресурса отделяется от параметров знаком вопроса ?.
  2. Параметры передаются парами ключ=значение.
  3. Несколько параметров объединяются между собой символом амперсанда &.
  4. Все специальные символы, кириллица, пробелы и знаки пунктуации в значениях должны быть закодированы в формате URL-encoding.

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

Распространенные форматы параметров фильтрации в REST API

Если документация отсутствует или ограничена, на практике чаще всего встречаются следующие варианты именования параметров отбора по дате:

  1. Точная дата: created_at=2017-04-13, date=2017-04-13.
  2. Диапазон дат: created_at_from=2017-04-01&created_at_to=2017-04-30, from=...&to=..., date_from=...&date_to=..., since=...&until=....
  3. Вложенные структуры фильтрации (массивы параметров): filter[created_at]=... или filter[created_at][gte]=...&filter[created_at][lte]=....
  4. Стандарт OData: $filter=created_at ge datetime'2017-04-13T00:00:00'.

Исправление ошибок в заголовках и настройках соединения

Проанализируем исходный код формирования запроса и устраним распространенные технические неточности:

  1. Заголовок Content-Type: В GET-запросах отсутствует передаваемое тело, поэтому указывать Content-Type не имеет смысла, данный заголовок является избыточным.
  2. Несоответствие форматов Accept: Если сервер отдает XML-структуру (как показано в примере с тегами <item>), заголовок Accept: application/json может приводить к ошибкам либо к попытке сервера преобразовать ответ. Если нам нужен XML, следует указывать application/xml или text/xml.
  3. Кодировка CESU-8: Кодировка CESU-8 не является стандартом в веб-разработке. Для корректной работы с подавляющим большинством HTTP-сервисов применяется UTF-8. Чтение тела ответа также следует выполнять в кодировке UTF-8 или без параметров (по умолчанию платформа использует UTF-8).
  4. Защищенное соединение: Если обращение выполняется по протоколу HTTPS, в конструкторе HTTPСоединение необходимо передать объект ЗащищенноеСоединениеOpenSSL.

Пример формирования GET-запроса с отбором по дате

Посмотрим на пример кода 1С, в котором формируются параметры фильтрации, выполняется URL-кодирование и отправляется GET-запрос:


Сервер = "мойсайт.рф";
БазовыйАдрес = "/api/items";

// Подготовим значения параметров
НомерСтраницы = 1;
ДатаНачала = '20170413000000';
СтрокаДаты = Формат(ДатаНачала, "ДФ=yyyy-MM-dd");

// Выполняем экранирование параметров для URL
ЗакодированнаяДата = КодироватьСтроку(СтрокаДаты, СпособКодированияСтроки.КодировкаURL);

// Собираем строку запроса с отбором и пагинацией
ПараметрыЗапроса = "page=" + НомерСтраницы + "&created_at_from=" + ЗакодированнаяДата;
АдресРесурса = БазовыйАдрес + "?" + ПараметрыЗапроса;

// Инициализируем защищенное соединение (при необходимости)
Защита = Новый ЗащищенноеСоединениеOpenSSL();
HTTPСоединение = Новый HTTPСоединение(Сервер, 443, , , , 30, Защита);

HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса);
HTTPЗапрос.Заголовки.Вставить("Accept", "application/xml, text/xml");

ОтветСервера = HTTPСоединение.Получить(HTTPЗапрос);

Если ОтветСервера.КодСостояния = 200 Тогда
    ТелоОтвета = ОтветСервера.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
    // Переходим к парсингу полученных данных
Иначе
    ВызватьИсключение "Ошибка HTTP-запроса: " + ОтветСервера.КодСостояния;
КонецЕсли;

Обработка и парсинг XML-ответа в 1С

После успешного получения ответа данные необходимо разобрать. Для эффективной работы с XML-документами в платформе 1С предусмотрен объект ЧтениеXML, который позволяет последовательно прочитать все узлы без избыточной нагрузки на оперативную память:


Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(ТелоОтвета);

Пока Чтение.Прочитать() Цикл
    Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента И Чтение.Имя = "item" Тогда
        // Считываем данные одного элемента
        ТекущийID = "";
        ТекущееИмя = "";
        ТекущаяДатаСоздания = "";
        
        Пока Чтение.Прочитать() Цикл
            Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
                ИмяУзла = Чтение.Имя;
                Чтение.Прочитать(); // Переход к текстовому значению
                Если ИмяУзла = "id" Тогда
                    ТекущийID = Чтение.Значение;
                ИначеЕсли ИмяУзла = "first_name" Тогда
                    ТекущееИмя = Чтение.Значение;
                ИначеЕсли ИмяУзла = "created_at" Тогда
                    ТекущаяДатаСоздания = Чтение.Значение;
                КонецЕсли;
            ИначеЕсли Чтение.ТипУзла = ТипУзлаXML.КонецЭлемента И Чтение.Имя = "item" Тогда
                Прервать; // Завершили чтение элемента
            КонецЕсли;
        КонецЦикла;
        
        // Обработка полученных значений (запись в справочник, ТЗ и т.д.)
    КонецЕсли;
КонецЦикла;

Чтение.Закрыть();

Альтернативное решение: фильтрация на стороне 1С при отсутствии API

В ситуации, когда разработчик сайта не реализовал серверную фильтрацию и связаться с ним невозможно, единственным выходом остается постраничный обход всех данных через цикл по параметру page и наложение отбора внутри 1С:

  1. В цикле инкрементируем номер страницы (page=1, page=2 и т.д.).
  2. Считываем каждую страницу и разбираем узлы <item>.
  3. Сравниваем строковое или приведенное к типу Дата значение поля <created_at> с требуемым периодом.
  4. Если сервер отдает элементы, отсортированные по дате создания, цикл постраничной загрузки можно прервать досрочно, как только дата элемента выйдет за рамки нужного интервала.
← На главную