Как правильно вернуть JSON в кодировке UTF-8 из HTTP-сервиса 1С и решить проблемы с кодировкой веб-сервера

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

При интеграции систем на платформе 1С с веб-приложениями часто возникает задача передачи данных в формате JSON через HTTP-сервисы. Несмотря на кажущуюся простоту, разработчики часто сталкиваются с неочевидными проблемами: пустой строкой на выходе, некорректным заполнением заголовков ответа, ошибками разбора (парсинга) JSON на клиенте или искажением кодировки веб-сервером. В этой статье мы подробно разберем, как правильно сформировать JSON в кодировке UTF-8, корректно настроить HTTP-ответ и обойти «подводные камни» конфигурации веб-сервера Apache.

Метод 1. Формирование JSON в строку в оперативной памяти

Самый простой и распространенный способ передать JSON-структуру клиенту — сформировать ее в виде строки в оперативной памяти 1С. Рассмотрим пошаговый алгоритм реализации этого метода:

  1. Создаем исходную структуру данных (соответствие или структуру 1С).
  2. Инициализируем объект ЗаписьJSON и подготавливаем его к записи в строку.
  3. Сериализуем данные с помощью системной функции ЗаписатьJSON.
  4. Закрываем запись и получаем итоговую строку.

Проанализируем пример готового кода для HTTP-сервиса:


// Шаг 1. Готовим данные для отправки
СтруктураВывода = Новый Структура;
СтруктураВывода.Вставить("remember", Ложь);
СтруктураВывода.Вставить("status", Истина);

// Шаг 2. Инициализируем запись JSON в строку
ЗаписьJSON = Новый ЗаписьJSON;
ПараметрыЗаписи = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет);
ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписи);

// Шаг 3. Сериализуем структуру 1С в JSON
ЗаписатьJSON(ЗаписьJSON, СтруктураВывода);

// Шаг 4. Получаем строку и закрываем объект
СтрокаJSON = ЗаписьJSON.Закрыть();

Этот способ идеально подходит для небольших пакетов данных, так как строка целиком размещается в оперативной памяти сервера приложений 1С.

Метод 2. Потоковое формирование JSON (через ПотокВПамяти)

Если объем передаваемых данных велик или требуется оптимизировать работу с памятью, целесообразно использовать потоковую запись через ПотокВПамяти. Распространенной ошибкой разработчиков является попытка получить строку методом ЗаписьJSON.Закрыть() при открытом потоке — в этом случае метод возвращает Неопределено.

Выясним причину: при записи в поток объект ЗаписьJSON сбрасывает данные напрямую в буфер потока, а не накапливает их в строковой переменной платформы. Чтобы корректно получить результат, мы должны проделать следующие действия:


// Создаем поток в памяти
Поток = Новый ПотокВПамяти;

ЗаписьJSON = Новый ЗаписьJSON;
// Открываем поток с явным указанием кодировки UTF-8
ЗаписьJSON.ОткрытьПоток(Поток, "UTF-8");

// Записываем данные в поток
ЗаписатьJSON(ЗаписьJSON, СтруктураВывода);
// Обязательно сначала закрываем ЗаписьJSON, чтобы сбросить буферы в поток
ЗаписьJSON.Закрыть(); 

// Получаем двоичные данные из потока и закрываем его
ДвоичныеДанные = Поток.ЗакрытьИПолучитьДвоичныеДанные();

// Преобразуем двоичные данные в строку UTF-8
СтрокаJSON = ПолучитьСтрокуИзДвоичныхДанных(ДвоичныеДанные, КодировкаТекста.UTF8);

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


Ответ = Новый HTTPСервисОтвет(200);
Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
Ответ.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанные);

Как правильно сконструировать HTTP-ответ в 1С

Частой ошибкой при создании веб-сервисов является путаница между заголовками (Headers) и телом (Body) HTTP-ответа. Попытки передать JSON-строку в заголовках (например, через Ответ.Заголовки.Вставить("result", СтрокаJSON)) приводят к падению сервиса или некорректной интерпретации ответа клиентом.

Рассмотрим правильный шаблон формирования ответа:


Ответ = Новый HTTPСервисОтвет(200);

// Очищаем заголовки (при необходимости)
Ответ.Заголовки.Очистить();

// Указываем тип контента. Для JSON это строго application/json
Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");

// Устанавливаем куки (Cookie), если это требуется для авторизации
ВремяЖизни = "3600"; // Время жизни куки в секундах
Ответ.Заголовки.Вставить("Set-Cookie", "token=" + ТокенПользователя + "; Max-Age=" + ВремяЖизни + "; HttpOnly; SameSite=Lax;");

// Записываем JSON-строку непосредственно в тело ответа
Ответ.УстановитьТелоИзСтроки(СтрокаJSON, "UTF-8", ИспользованиеByteOrderMark.НеИспользовать);

Обратите внимание на параметр ИспользованиеByteOrderMark.НеИспользовать. Веб-клиенты (особенно JS-парсеры в браузерах) плохо реагируют на наличие BOM (Byte Order Mark) сигнатуры в начале JSON-файла, поэтому его добавление следует отключать.

Решение проблемы с кодировкой на стороне веб-сервера Apache

Иногда код в 1С написан абсолютно верно, заголовки установлены, но при попытке прочитать ответ в JS-коде (например, через $.ajax или fetch) клиент падает с ошибкой синтаксического разбора JSON. При этом в отладчике мы можем видеть кракозябры вместо кириллицы.

Выясним причину этой проблемы. При публикации базы 1С на веб-сервере Apache, последний выступает в роли прокси-сервера. Если в конфигурационном файле Apache (httpd.conf) включена принудительная кодировка по умолчанию, веб-сервер переопределит заголовки 1С и отдаст текстовые данные в неверной кодировке.

Проанализируем, как решить эту проблему в настройках Apache:

  1. Откройте конфигурационный файл веб-сервера Apache (обычно это httpd.conf в папке conf установленного сервера).
  2. Найдите директиву AddDefaultCharset.
  3. Если она имеет значение, отличное от UTF-8 (например, AddDefaultCharset windows-1251), это и является причиной искажения данных.
  4. Измените значение директивы, отключив принудительное переопределение кодировок со стороны Apache, чтобы он доверял заголовкам, сформированным платформой 1С: AddDefaultCharset Off Или явно укажите использование UTF-8 в качестве глобального стандарта: AddDefaultCharset UTF-8
  5. Перезапустите службу веб-сервера Apache, чтобы изменения вступили в силу.

Мифы о методах GET и POST в контексте работы с JSON

Существует заблуждение, что метод GET в HTTP-сервисах 1С не умеет работать с форматом JSON. Это не так. Ограничение касается только передачи данных от клиента к серверу 1С:

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

← На главную