Почему HTTP-сервис в 1С формирует пустой XML и как правильно передавать данные между базами?

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

При разработке интеграционных механизмов на платформе 1С разработчики часто сталкиваются с ситуацией, когда один и тот же программный код выборки данных и генерации XML-документа корректно отрабатывает во внешней обработке, но при выполнении в модуле HTTP-сервиса возвращает лишь корневой тег (например, <Реализации/>) без строк с данными. Проанализируем причины такого поведения платформы, разберем типовые архитектурные ошибки и рассмотрим правильные варианты реализации передачи информации.

Причина 1: Права доступа сервисного пользователя и ограничения RLS

Когда мы тестируем код в интерактивной обработке, сеанс запускается под текущим пользователем системы (как правило, с полными административными правами). Вызов же HTTP-сервиса происходит в контексте пользователя, указанного в файле публикации (default.vrd) или переданного в заголовке базовой аутентификации.

Если у сервисной учетной записи отсутствуют права на чтение требуемых метаданных либо включен механизм ограничения прав на уровне записей (RLS), запрос к базе данных вернет пустую выборку. В результате объект ЗаписьXML создаст только открывающий и закрывающий корневые теги.

Для гарантированного обхода ограничений прав в коде метода HTTP-сервиса можно принудительно включить привилегированный режим:


Функция ВыгрузитьРеализацииGET(Запрос)
    
    УстановитьПривилегированныйРежим(Истина);
    
    // Формирование выборки данных и XML
    
    Ответ = Новый HTTPСервисОтвет(200);
    Возврат Ответ;
    
КонецФункции

Причина 2: Специфика типизации параметров GET-запроса

Параметры, передаваемые в строке адреса (query parameters), считываются через коллекцию HTTPСервисЗапрос.ПараметрыЗапроса исключительно в виде строковых значений. Если в запросе к данным условие отбора ожидает дату или ссылку, а разработчик передает нетипизированную строку, запрос не вернет ни одной записи.

Разберем по шагам, как правильно преобразовать входящие параметры:

  1. Извлекаем строковое значение параметра из коллекции Запрос.ПараметрыЗапроса.Получить("ДатаНачала").
  2. Преобразуем полученную строку к целевому типу данных, например, с помощью функции XMLЗначение() или явного приведения к типу Дата.
  3. Передаем преобразованное значение в параметры запроса к базе данных.

СтрокаДаты = Запрос.ПараметрыЗапроса.Получить("ДатаС");
Если ЗначениеЗаполнено(СтрокаДаты) Тогда
    ДатаС = XMLЗначение(Тип("Дата"), СтрокаДаты);
    ЗапросКБД.УстановитьПараметр("ДатаС", ДатаС);
КонецЕсли;

Причина 3: Кодирование специальных символов и кириллицы

При передаче строковых параметров в строке URL пробелы, кириллические буквы и спецсимволы могут искажаться сервером публикации, если они не были экранированы. Для предотвращения повреждения данных при передаче параметров через строку запроса необходимо использовать функции экранирования:

  1. На стороне клиента или базы-отправителя кодируем строковое значение с помощью метода КодироватьСтроку().
  2. На стороне HTTP-сервиса базы-получателя восстанавливаем исходный текст с помощью метода РаскодироватьСтроку().

// Пример на стороне отправителя:
ПараметрЗапроса = КодироватьСтроку("Тиара", СпособКодированияСтроки.КодировкаURL);

// Пример на стороне HTTP-сервиса (получателя):
ИмяКлиента = РаскодироватьСтроку(Запрос.ПараметрыЗапроса.Получить("Клиент"), СпособКодированияСтроки.КодировкаURL);

Причина 4: Ошибки буферизации объекта ЗаписьXML

При генерации XML-строки в оперативной памяти с помощью метода ЗаписьXML.УстановитьСтроку() обязательно требуется завершить формирование вызовом метода Закрыть() перед извлечением результирующего текста через ПолучитьСтроку(). В противном случае внутренний буфер записи может не сбросить закрывающие теги и часть данных.


ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку("UTF-8");

ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписьXML.ЗаписатьНачалоЭлемента("Реализации");

Выборка = ЗапросКБД.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    ЗаписьXML.ЗаписатьНачалоЭлемента("СтрокаРеализации");
    ЗаписьXML.ЗаписатьАтрибут("Номер", Строка(Выборка.Номер));
    ЗаписьXML.ЗаписатьАтрибут("Сумма", XMLСтрока(Выборка.СуммаДокумента));
    ЗаписьXML.ЗаписатьАтрибут("Контрагент", Строка(Выборка.КонтрагентНаименование));
    ЗаписьXML.ЗаписатьКонецЭлемента();
КонецЦикла;

ЗаписьXML.ЗаписатьКонецЭлемента(); // Реализации

ТекстXML = ЗаписьXML.Закрыть();

Ответ = Новый HTTPСервисОтвет(200);
Ответ.Заголовки.Вставить("Content-Type", "application/xml; charset=utf-8");
Ответ.УстановитьТелоИзСтроки(ТекстXML, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
Возврат Ответ;

Рекомендации по выбору архитектуры: GET, POST и форматы данных

Рассмотрим несколько правил проектирования HTTP-сервисов в 1С:

  1. Выбор метода запроса: Метод GET предназначен исключительно для получения данных по параметрам в строке URL. Длина GET-запроса ограничена веб-серверами (обычно от 2 до 8 Кб). Если требуется передавать большие списки фильтров или создавать/изменять данные, всегда используем метод POST с передачей информации в теле запроса.
  2. Формат JSON vs XML: Формат JSON является более компактным, нативным для веб-технологий и потребляет меньше серверных ресурсов при разборе платформенными функциями ПрочитатьJSON() и ЗаписатьJSON().
  3. Использование стандартного OData: Если требуется стандартная выборка реквизитов типовых документов (номер, дата, сумма, контрагент), целесообразно использовать встроенный интерфейс OData платформы 1С:Предприятие без ручного написания собственного HTTP-сервиса.
← На главную