Как исправить ошибку Syntax error в JSON-запросе при интеграции 1С с внешними API

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

При работе с внешними сервисами через HTTP-запросы программисты 1С часто сталкиваются с ошибкой "Invalid JSON data in request body: Syntax error". Эта ситуация особенно характерна для интеграции с API, работающими по протоколу JSON-RPC 2.0, такими как сервис Plusofon. В данной статье мы подробно разберем, почему ручное формирование строки JSON приводит к сбоям, как правильно использовать объекты платформы для сериализации данных и как решить проблему совместимости со старыми версиями платформы.

Анализ проблемы: почему ручная сборка JSON — это плохой путь

Рассмотрим типичную ошибку начинающего разработчика: попытку собрать JSON-пакет с помощью объекта ЗаписьТекста или простого сложения строк. На первый взгляд код выглядит корректно, однако дьявол кроется в деталях:

  1. Экранирование спецсимволов: Любой слэш, кавычка или символ переноса строки в данных должен быть правильно экранирован. Вручную это сделать сложно и трудозатратно.
  2. Типизация данных: В JSON числа, строки и булевы значения записываются по-разному. Лишние кавычки вокруг числа или их отсутствие вокруг строки делают весь пакет невалидным.
  3. Маркер BOM (Byte Order Mark): Это скрытые символы в начале файла или строки в кодировке UTF-8, которые 1С может добавлять автоматически. Многие современные веб-серверы не понимают BOM и выдают синтаксическую ошибку, так как ожидают, что первым символом будет открывающая фигурная скобка {.

Проанализируем пример ошибки, которую возвращает сервер:

{"jsonrpc":"2.0","id":null,"result":null,"error":{"code":0,"message":"Invalid JSON data in request body: Syntax error."}}

Обратите внимание на поле id: null в ответе. Это часто означает, что сервер даже не смог прочитать поле id из вашего запроса, так как "споткнулся" на синтаксисе еще в самом начале тела сообщения.

Правильный подход: использование структур и ЗаписьJSON

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

Разберем по шагам, как сформировать запрос для метода flash-call/send. Нам нужно передать структуру, в которой одно из полей (params) само является структурой.

Реализация функции преобразования данных

Для удобства создадим универсальную функцию, которая превращает любую структуру 1С в валидную строку JSON. Выясним причину использования объекта ЗаписьJSON: он автоматически обрабатывает все нюансы кодирования.


Функция ПреобразоватьВJson(ОбъектДанных) Экспорт
    
    ЗаписьJSON = Новый ЗаписьJSON;
    ПараметрыЗаписи = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет); 
    ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписи);
    
    ЗаписатьJSON(ЗаписьJSON, ОбъектДанных);
    
    Результат = ЗаписьJSON.Закрыть();
    Возврат Результат;
    
КонецФункции

В этом примере мы используем ПереносСтрокJSON.Нет, чтобы получить компактную строку, которая лучше подходит для передачи по сети.

Формирование структуры запроса

Теперь подготовим сами данные для отправки. Согласно документации API, нам нужны поля jsonrpc, method, params и id. Посмотрим на пример кода:


// Создаем вложенную структуру параметров
ПараметрыВызова = Новый Структура;
ПараметрыВызова.Вставить("phone", "79991234567"); // Номер телефона лучше передавать строкой

// Создаем основную структуру запроса
СтруктураЗапроса = Новый Структура;
СтруктураЗапроса.Вставить("jsonrpc", "2.0");
СтруктураЗапроса.Вставить("method", "flash-call/send");
СтруктураЗапроса.Вставить("params", ПараметрыВызова);
СтруктураЗапроса.Вставить("id", 1); // ID запроса как число

// Получаем итоговую JSON-строку
ТекстЗапроса = ПреобразоватьВJson(СтруктураЗапроса);

Решение проблемы BOM и отправка HTTP-запроса

Если ваша конфигурация работает в режиме совместимости (например, 8.2.13 или 8.3.6), платформа может принудительно добавлять BOM при записи тела запроса. Именно это часто становится причиной "Syntax error" на стороне сервера.

Разберем, как правильно установить тело запроса, используя метод УстановитьТелоИзСтроки с явным указанием параметров кодировки. Это критически важный момент для стабильной работы интеграции.


Сервер = "new-api.plusofon.ru";
Ресурс = "/flash-call/send";

// Настройка защищенного соединения
Защита = Новый ЗащищенноеСоединениеOpenSSL();
HTTPСоединение = Новый HTTPСоединение(Сервер, 443, , , , , Защита);

HTTPЗапрос = Новый HTTPЗапрос(Ресурс);
HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/json");
HTTPЗапрос.Заголовки.Вставить("Authorization", "Bearer ВАШ_ТОКЕН");

// Устанавливаем тело запроса БЕЗ использования Byte Order Mark (BOM)
HTTPЗапрос.УстановитьТелоИзСтроки(ТекстЗапроса, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

Попытка
    Ответ = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
    ТекстОтвета = Ответ.ПолучитьТелоКакСтроку();
    // Дальнейшая обработка ответа через ЧтениеJSON
Исключение
    Сообщить("Ошибка сетевого соединения: " + ОписаниеОшибки());
КонецПопытки;

Дополнительные рекомендации по работе с API

Проанализируем еще несколько нюансов, которые помогут избежать ошибок при интеграции:

  1. Тип данных поля "phone": Хотя некоторые API указывают тип integer для телефона, на практике лучше использовать string. Номера телефонов могут начинаться с нуля или быть слишком длинными для 32-битного целого числа, что приведет к переполнению в некоторых парсерах.
  2. Заголовок Accept: Рекомендуется всегда добавлять заголовок HTTPЗапрос.Заголовки.Вставить("Accept", "application/json"). Это гарантирует, что даже в случае внутренней ошибки сервер постарается вернуть вам описание проблемы в формате JSON, а не в виде HTML-страницы.
  3. Логирование: При отладке всегда сохраняйте итоговую строку ТекстЗапроса в текстовый лог. Вы можете скопировать её и проверить в любом онлайн-валидаторе JSON. Если валидатор говорит, что всё ок, а сервер 1С ругается — значит проблема в BOM или кодировке при передаче.

Таким образом, мы выяснили, что для успешной работы с JSON в 1С необходимо отказаться от методов ручной склейки строк в пользу системных объектов Структура, Массив и ЗаписьJSON. Особое внимание следует уделять настройке ИспользованиеByteOrderMark.НеИспользовать, которая снимает большинство проблем с несовместимостью кодировок на стороне веб-серверов.

← На главную