Как передать большой объем данных в формате JSON через HTTP-сервис в 1С без ошибок

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

При работе с интеграциями в 1С программисты часто сталкиваются с ситуацией, когда небольшие пакеты данных (например, массив из нескольких строк) передаются через HTTP-сервисы без проблем, но при попытке отправить массив из 10 000 и более элементов система выдает ошибку. Часто это проявляется как «ошибка потока» или длительное ожидание с последующим разрывом соединения, при этом код на стороне приемника даже не начинает выполняться. Разберем подробно, почему так происходит и как оптимизировать процесс передачи больших объемов данных.

Анализ причин сбоя при передаче больших JSON

Прежде всего, проанализируем ситуацию: если на малых объемах всё работает корректно, значит, программная логика формирования JSON верна. Ошибка на больших объемах обычно сигнализирует об одном из трех факторов:

  1. Превышение таймаута соединения: Время, затраченное на формирование и передачу огромного текста, превышает настройки ожидания в HTTPСоединение.
  2. Ограничения веб-сервера (IIS или Apache): Веб-сервер, на котором опубликован сервис 1С, имеет встроенные лимиты на размер тела POST-запроса.
  3. Нехватка оперативной памяти: Попытка сформировать гигантскую строку в памяти перед отправкой может привести к деградации производительности или аварийному завершению процесса.

Шаг 1. Проверка сериализации и исключение ошибок в данных

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


ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
Попытка
    ЗаписатьJSON(ЗаписьJSON, ВашМассив);
    ТекстJSON = ЗаписьJSON.Закрыть();
    Сообщить("Длина сформированной строки: " + СтрДлина(ТекстJSON));
Исключение
    Сообщить("Ошибка преобразования: " + ОписаниеОшибки(), СтатусСообщения.Важное);
КонецПопытки;

Если этот код выполняется успешно и вы видите длину строки, значит проблема не в структуре JSON, а в процессе его транспортировки.

Шаг 2. Настройка таймаутов в HTTPСоединение

Выясним причину долгого ожидания. По умолчанию таймаут в 1С может быть недостаточным для обработки и передачи пакета в несколько десятков мегабайт. Попробуем увеличить время ожидания в конструкторе объекта HTTPСоединение. Параметр таймаута указывается в секундах.


// Устанавливаем таймаут 60 секунд (или больше, в зависимости от объема)
Соединение = Новый HTTPСоединение(Сервер, Порт, Пользователь, Пароль, Прокси, 60);
Запрос = Новый HTTPЗапрос(Ресурс);
Запрос.УстановитьТелоИзСтроки(ТекстJSON);
Ответ = Соединение.ОтправитьДляОбработки(Запрос);

Если увеличение таймаута до 120–300 секунд не помогает, и ошибка «вылетает» почти сразу или сервер возвращает 404.13 или 413, значит, мы столкнулись с лимитами веб-сервера.

Шаг 3. Настройка веб-сервера IIS для приема больших запросов

Проанализируем ситуацию со стороны сервера. Если вы используете IIS, он по умолчанию ограничивает размер запроса (около 30 МБ). Если ваш JSON превышает этот лимит, запрос будет «отсечен» еще до того, как управление будет передано платформе 1С.

Необходимо внести изменения в файл web.config вашего опубликованного сервиса:

  1. Найдите секцию <system.webServer> и добавьте или измените параметр maxAllowedContentLength (значение указывается в байтах). Например, для установки лимита в 100 МБ:
    
    <security>
        <requestFiltering>
            <requestLimits maxAllowedContentLength="104857600" />
        </requestFiltering>
    </security>
    
  2. В секции <system.web> проверьте параметр maxRequestLength (значение в килобайтах): <httpRuntime maxRequestLength="102400" />
  3. Если используется HTTPS, обратите внимание на параметр uploadReadAheadSize в настройках IIS (раздел "Editor Configuration" -> "Server Runtime"), который определяет объем данных, кэшируемых сервером перед передачей.

Шаг 4. Оптимизация передачи данных через потоки (Stream)

Работа с огромными строками через УстановитьТелоИзСтроки() крайне неэффективна, так как данные дублируются в памяти. Правильнее использовать запись во временный файл и отправку этого файла в поток. Рассмотрим, как это реализовать:


ИмяФайла = ПолучитьИмяВременногоФайла("json");
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ОткрытьФайл(ИмяФайла, "UTF-8");
ЗаписатьJSON(ЗаписьJSON, ВашМассив);
ЗаписьJSON.Закрыть();

// Отправляем файл напрямую, не загружая его целиком в строку
Запрос = Новый HTTPЗапрос(Ресурс);
Запрос.УстановитьТелоИзФайла(ИмяФайла);

Соединение = Новый HTTPСоединение(Сервер, , , , , 120);
Ответ = Соединение.ОтправитьДляОбработки(Запрос);

// Удаляем временный файл
УдалитьФайлы(ИмяФайла);

Этот метод значительно снижает потребление оперативной памяти на клиенте. На стороне сервера (в самом HTTP-сервисе) также рекомендуется использовать метод запроса Запрос.ПолучитьТелоКакПоток() вместо получения строки, чтобы начать обработку данных по мере их поступления.

Шаг 5. Использование сжатия и разбиение на части

Если объем данных всё равно остается критическим, рассмотрим дополнительные способы оптимизации:

Таким образом, решение проблемы «большого JSON» заключается в комплексном подходе: от настройки лимитов веб-сервера IIS/Apache до перехода на потоковую работу с данными в коде 1С. Это позволит избежать ошибок переполнения памяти и обеспечит стабильную работу интеграционных сервисов.

← На главную