Как исправить ошибку «Unable to parse JSON request» при отправке запроса из 1С

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

При интеграции 1С с внешними веб-сервисами и API разработчики нередко сталкиваются с ситуацией, когда отправленный корректный JSON-документ не принимается сервером. В ответ API возвращает ошибку разбора, например, «Unable to parse JSON request» или «Invalid JSON». При этом локальная проверка текста в редакторах показывает валидную структуру, а аналогичный запрос из другой конфигурации или через сторонние утилиты может выполняться успешно. Разберем по шагам, почему возникает эта проблема и как правильно настроить передачу данных в 1С.

Причины возникновения ошибки разбора JSON

Проанализируем ситуацию и выясним, почему принимающий веб-сервер не может обработать сформированный запрос:

  1. Наличие метки порядка байтов (BOM): По стандарту RFC 8259 формат JSON не должен содержать сигнатуру BOM (байты EF BB BF в начале потока UTF-8). Большинство современных серверных библиотек парсинга строго придерживаются стандарта и аварийно завершают обработку, встретив невидимые служебные байты перед первой открывающей скобкой { или [.
  2. Поведение платформы 1С по умолчанию: При вызове метода УстановитьТелоИзСтроки объекта HTTPЗапрос без явного указания режима BOM платформа может автоматически добавлять сигнатуру байтов к строке в кодировке UTF-8.
  3. Особенности режима совместимости: В конфигурациях на обычных формах (таких как УПП 1.3 или КА 1.1), работающих в режиме совместимости с платформой 8.2, сетевые объекты и параметры по умолчанию могут вести себя иначе, чем в современных конфигурациях на управляемых формах.
  4. Отсутствие заголовка Content-Type: Если в заголовках не передается application/json; charset=utf-8, веб-сервер может попытаться интерпретировать UTF-8 в другой кодировке (например, Windows-1251 или ISO-8859-1), что при наличии кириллицы приведет к искажению синтаксиса.

Способ 1. Явное отключение BOM при установке тела запроса

Рассмотрим основной и самый правильный способ решения проблемы штатными средствами 1С:Предприятие. При формировании тела HTTPЗапрос необходимо явно передать третий параметр — значение перечисления ИспользованиеByteOrderMark.НеИспользовать.

Посмотрим на пример правильной инициализации запроса:


// Формируем JSON-строку
Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
ЗаписатьJSON(Запись, СтруктураДанных);
СтрокаJSON = Запись.Закрыть();

// Формируем HTTP-запрос с отключением BOM
Запрос = Новый HTTPЗапрос(URIСтрока);
Запрос.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
Запрос.УстановитьТелоИзСтроки(СтрокаJSON, "UTF-8", ИспользованиеByteOrderMark.НеИспользовать);

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

В более старых релизах платформы или специфических режимах совместимости иногда применялся хак с указанием кодировки "CESU-8", которая подавляла вставку BOM. Однако в современном коде рекомендуется всегда использовать стандартный UTF-8 совместно с ИспользованиеByteOrderMark.НеИспользовать.

Способ 2. Передача тела через двоичные данные

Если мы хотим полностью контролировать побайтовое содержимое тела запроса и исключить влияние внутренних механизмов работы HTTPЗапрос со строками, воспользуемся явной конвертацией в двоичные данные. Разберем этот вариант:


// Преобразуем строку в двоичные данные без добавления BOM (третий параметр - Ложь)
ДвоичныеДанныеТела = ПолучитьДвоичныеДанныеИзСтроки(СтрокаJSON, КодировкаТекста.UTF8, Ложь);

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

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

Такой подход гарантирует, что в поток отправки попадут исключительно байты текста JSON без каких-либо служебных префиксов.

Способ 3. Тонкая настройка сериализации через ПараметрыЗаписиJSON

Некоторые внешние API чувствительны не только к BOM, но и к форматированию пробелов, переносов строк или экранированию спецсимволов. Рассмотрим, как настроить сериализатор ЗаписьJSON для получения компактной и строгой строки:


ПараметрыЗаписи = Новый ПараметрыЗаписиJSON(
    ПереносСтрокJSON.Нет,      // Отключаем лишние переносы строк
    " ",                       // Символ отступа
    Истина,                    // Экранировать специальные символы
    ЭкранированиеСимволовJSON.СимволыВнеASCII // Корректная обработка национальных символов
);

Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку(ПараметрыЗаписи);
ЗаписатьJSON(Запись, СтруктураДанных);
СтрокаJSON = Запись.Закрыть();

Использование явных параметров форматирования предотвращает искажение служебных символов внутри строковых значений (например, в паролях, логинах и токенах авторизации).

Способ 4. Использование системного COM-объекта WinHTTP

В конфигурациях на обычных формах (например, в УПП 1.3), где могут действовать ограничения старых версий платформы, альтернативным вариантом является отправка запроса через системный COM-объект операционной системы. Разберем пример реализации:


HTTP = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
HTTP.Open("POST", АдресСервиса, Ложь);
HTTP.SetRequestHeader("Content-Type", "application/json; charset=utf-8");

// Отправляем тело запроса напрямую
HTTP.Send(СтрокаJSON);

КодСостояния = HTTP.Status;
ТекстОтвета = HTTP.ResponseText;

Объект WinHttp.WinHttpRequest.5.1 передает строку напрямую в системный стек Windows без автоматического добавления UTF-8 BOM, что решает проблему совместимости с внешними веб-серверами.

← На главную