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

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

Разработка HTTP-сервисов на платформе «1С:Предприятие 8.3» — это эффективный способ интеграции системы с внешними приложениями. Однако начинающие разработчики часто сталкиваются с типовыми ошибками при формировании ответов в формате JSON. Рассмотрим подробно причины возникновения ошибки в методе ЗаписатьJSON, разберем проблемы с правами доступа и научимся правильно обрабатывать параметры запросов.

Проблема 1: Сериализация сложных типов данных

Одной из самых частых причин падения метода ЗаписатьJSON является попытка передать в него объект, который платформа не может автоматически преобразовать в строку JSON. К таким объектам относятся любые ссылки (СправочникСсылка, ДокументСсылка), перечисления, а также специфические объекты вроде ХранилищеЗначения.

Проанализируем ситуацию: когда вы выбираете данные из справочника, например, через Выбрать() или НайтиПоКоду(), и напрямую вставляете результат в структуру, вы передаете ссылку, а не текстовое представление или код элемента. Метод ЗаписатьJSON ожидает только простые типы данных: строка, число, булево, дата.

Разберем правильный подход к формированию данных для массива или структуры:


// Неправильно:
Данные.Вставить("ЕдиницаИзмерения", Выборка.Единица); // Здесь передается Ссылка

// Правильно:
Данные.Вставить("ЕдиницаИзмерения", Строка(Выборка.Единица)); // Передаем наименование
// или
Данные.Вставить("ЕдиницаИзмеренияКод", Выборка.Единица.Код); // Передаем код

Если вам необходимо передать сложный объект целиком, рекомендуется использовать СериализаторXDTO, который умеет раскладывать объекты 1С в формат, пригодный для записи в поток JSON. Однако для простых API ручное формирование структуры с приведением к строке или числу является более производительным методом.

Проблема 2: Именование ключей в JSON и ограничения объекта Структура

В языке 1С объект Структура имеет жесткие требования к именованию своих ключей: они должны соответствовать правилам именования переменных (не могут содержать пробелов, начинаться с цифр и содержать спецсимволы). Если ваше API требует ключ с пробелом, например "номер карты", использование Структура приведет к ошибке еще на этапе написания кода или при попытке вставки ключа.

Выясним, как обойти это ограничение. Для формирования JSON-объектов с произвольными именами ключей следует использовать объект Соответствие. При сериализации через ЗаписатьJSON он превращается в обычный JSON-объект {}, но позволяет использовать любые строковые значения в качестве ключей.

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


ДанныеКарты = Новый Соответствие;
ДанныеКарты.Вставить("номер карты", Karta.Наименование); 
ДанныеКарты.Вставить("имя", Karta.Имя);
// Теперь ЗаписатьJSON обработает это без ошибок
ЗаписатьJSON(ЗаписьJSON, ДанныеКарты);

Важный совет: Старайтесь всегда использовать латиницу для ключей JSON. Это стандарт де-факто для веб-разработки, который поможет избежать проблем с кодировками на стороне потребителя вашего сервиса.

Проблема 3: Ошибки прав доступа (403 Forbidden / 405 Method Not Allowed)

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

  1. Права пользователя: Пользователь, под которым выполняется подключение (указанный в публикации на веб-сервере или передаваемый через Basic Auth), должен иметь роль с правом «Администрирование данных» или специальное право на запуск конкретного HTTP-сервиса.
  2. Публикация сервиса: Проверьте файл default.vrd. Убедитесь, что ваш сервис включен в список публикуемых.
  3. Методы HTTP: Ошибка 405 возникает, если вы обращаетесь к сервису методом GET, а в конфигураторе для этого шаблона настроен только метод POST.

Проблема 4: Параметры URL против параметров запроса

Рассмотрим ситуацию, когда сервис не возвращает данные при использовании параметров. В 1С существует два принципиально разных способа передачи данных в строке адреса:

Если вы перепутаете эти коллекции, метод Получить() вернет Неопределено, поиск в базе не сработает, и сервис вернет пустой ответ или ошибку 204 (No Content).

Итоговый пример корректного метода HTTP-сервиса

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


Функция ПолучитьДанныеКарты(Запрос)
    
    // 1. Получаем параметр из строки запроса (?number=...)
    КодКарты = Запрос.ПараметрыЗапроса.Получить("number");
    
    Если КодКарты = Неопределено Тогда
        Возврат Новый HTTPСервисОтвет(400); // Bad Request
    КонецЕсли;

    // 2. Поиск данных
    КартаСсылка = Справочники.ДисконтныеКарты.НайтиПоКоду(КодКарты);
    
    Если КартаСсылка.Пустая() Тогда
        Возврат Новый HTTPСервисОтвет(404); // Not Found
    КонецЕсли;

    // 3. Формируем данные через Соответствие для гибкости ключей
    ОтветСтруктура = Новый Соответствие;
    ОтветСтруктура.Вставить("card_number", СокрЛП(КартаСсылка.Наименование));
    ОтветСтруктура.Вставить("client_name", КартаСсылка.ВладелецКарты.Наименование);
    ОтветСтруктура.Вставить("status", "active");

    // 4. Сериализация
    ЗаписьJSON = Новый ЗаписьJSON;
    ЗаписьJSON.УстановитьСтроку();
    ЗаписатьJSON(ЗаписьJSON, ОтветСтруктура);
    СтрокаJSON = ЗаписьJSON.Закрыть();

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

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

Если вы продолжаете получать «Ошибку JSON» в сложных системах (например, в модулях ЭДО), помните: часто это происходит из-за того, что сервер вместо ожидаемого JSON прислал HTML-страницу с ошибкой (например, ошибку 500 от веб-сервера IIS или Apache). 1С пытается прочитать <html>...</html> как JSON и выдает исключение. В таких случаях всегда проверяйте текст ответа в отладчике перед вызовом ПрочитатьJSON.

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

← На главную