Разработка HTTP-сервисов на платформе «1С:Предприятие 8.3» — это эффективный способ интеграции системы с внешними приложениями. Однако начинающие разработчики часто сталкиваются с типовыми ошибками при формировании ответов в формате JSON. Рассмотрим подробно причины возникновения ошибки в методе ЗаписатьJSON, разберем проблемы с правами доступа и научимся правильно обрабатывать параметры запросов.
Одной из самых частых причин падения метода ЗаписатьJSON является попытка передать в него объект, который платформа не может автоматически преобразовать в строку JSON. К таким объектам относятся любые ссылки (СправочникСсылка, ДокументСсылка), перечисления, а также специфические объекты вроде ХранилищеЗначения.
Проанализируем ситуацию: когда вы выбираете данные из справочника, например, через Выбрать() или НайтиПоКоду(), и напрямую вставляете результат в структуру, вы передаете ссылку, а не текстовое представление или код элемента. Метод ЗаписатьJSON ожидает только простые типы данных: строка, число, булево, дата.
Разберем правильный подход к формированию данных для массива или структуры:
// Неправильно:
Данные.Вставить("ЕдиницаИзмерения", Выборка.Единица); // Здесь передается Ссылка
// Правильно:
Данные.Вставить("ЕдиницаИзмерения", Строка(Выборка.Единица)); // Передаем наименование
// или
Данные.Вставить("ЕдиницаИзмеренияКод", Выборка.Единица.Код); // Передаем код
Если вам необходимо передать сложный объект целиком, рекомендуется использовать СериализаторXDTO, который умеет раскладывать объекты 1С в формат, пригодный для записи в поток JSON. Однако для простых API ручное формирование структуры с приведением к строке или числу является более производительным методом.
В языке 1С объект Структура имеет жесткие требования к именованию своих ключей: они должны соответствовать правилам именования переменных (не могут содержать пробелов, начинаться с цифр и содержать спецсимволы). Если ваше API требует ключ с пробелом, например "номер карты", использование Структура приведет к ошибке еще на этапе написания кода или при попытке вставки ключа.
Выясним, как обойти это ограничение. Для формирования JSON-объектов с произвольными именами ключей следует использовать объект Соответствие. При сериализации через ЗаписатьJSON он превращается в обычный JSON-объект {}, но позволяет использовать любые строковые значения в качестве ключей.
Посмотрим на пример реализации с использованием Соответствие:
ДанныеКарты = Новый Соответствие;
ДанныеКарты.Вставить("номер карты", Karta.Наименование);
ДанныеКарты.Вставить("имя", Karta.Имя);
// Теперь ЗаписатьJSON обработает это без ошибок
ЗаписатьJSON(ЗаписьJSON, ДанныеКарты);
Важный совет: Старайтесь всегда использовать латиницу для ключей JSON. Это стандарт де-факто для веб-разработки, который поможет избежать проблем с кодировками на стороне потребителя вашего сервиса.
Если вы исправили код, но браузер или клиент выдает ошибку «Недостаточно прав для использования ресурса», необходимо проверить настройки безопасности. HTTP-сервисы в 1С работают под определенным пользователем. Проанализируем основные точки проверки:
default.vrd. Убедитесь, что ваш сервис включен в список публикуемых.GET, а в конфигураторе для этого шаблона настроен только метод POST.Рассмотрим ситуацию, когда сервис не возвращает данные при использовании параметров. В 1С существует два принципиально разных способа передачи данных в строке адреса:
/get_card/{nomer_karty}. Получаются через Запрос.ПараметрыURL.Получить("nomer_karty")./get_card?nomer_karty=123. Получаются через Запрос.ПараметрыЗапроса.Получить("nomer_karty").Если вы перепутаете эти коллекции, метод Получить() вернет Неопределено, поиск в базе не сработает, и сервис вернет пустой ответ или ошибку 204 (No Content).
С учетом всех разобранных ошибок, создадим надежный метод для получения данных о дисконтной карте:
Функция ПолучитьДанныеКарты(Запрос)
// 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 и логируйте описание ошибки через ИнформацияОбОшибке(). Это позволит вам мгновенно увидеть, какой именно элемент данных вызвал сбой сериализации.