Как исправить ошибку «Непредвиденный символ при чтении JSON» при интеграции 1С с Яндекс.Маркетом

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

При разработке интеграций с внешними сервисами, такими как Яндекс.Маркет, программисты 1С часто сталкиваются с ошибкой «Непредвиденный символ при чтении JSON». Эта ситуация особенно коварна тем, что сервер возвращает код состояния 200 (OK), подтверждая успешность запроса, но встроенная функция 1С ПрочитатьJSON() аварийно завершает работу. В данной статье мы подробно разберем, почему это происходит и как правильно настроить обмен данными, чтобы избежать подобных сбоев.

Выясняем причину: почему парсер JSON выдает ошибку

Первым делом проанализируем ситуацию, в которой возникает ошибка. Рассмотрим стандартный фрагмент кода, который обычно приводит к проблеме:


Ответ = HTTPОтвет.ПолучитьТелоКакСтроку("UTF-8");
Если HTTPОтвет.КодСостояния = 200 Тогда
    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.УстановитьСтроку(Ответ);
    ПараметрыJSON = ПрочитатьJSON(ЧтениеJSON); // Ошибка вылетает здесь
КонецЕсли;

Основная причина ошибки «Непредвиденный символ» заключается в том, что содержимое переменной Ответ на самом деле не является валидным JSON-объектом. Как показывает практика интеграции с API Яндекса, сервер может вернуть ответ в формате XML, если в запросе явно не указано иное. Посмотрим на пример «битого» ответа, который получает автор темы:

<response><status>OK</status><result><paging next-page-token="..."/>...

Поскольку XML начинается с символа <, парсер ЧтениеJSON моментально выдает исключение, так как ожидает увидеть открывающую фигурную скобку { или квадратную скобку [. Таким образом, проблема не в «плохом» символе внутри данных, а в неверном формате всего пакета данных.

Решение 1: Настройка HTTP-заголовков для управления форматом

Для того чтобы Яндекс.Маркет возвращал данные именно в формате JSON, необходимо правильно сконфигурировать заголовки HTTPЗапрос. Разберем два ключевых заголовка:

  1. Accept: Этот заголовок сообщает серверу, какой формат данных клиент (ваша 1С) ожидает получить в ответ. Для JSON это значение application/json.
  2. Content-Type: Этот заголовок указывает серверу формат данных, которые вы отправляете в теле запроса (например, параметры фильтрации в методе POST).

Рассмотрим пример правильной подготовки запроса в 1С:


ЗаголовокЗапроса = Новый Соответствие;
// Указываем, что хотим получить JSON
ЗаголовокЗапроса.Вставить("Accept", "application/json"); 
// Указываем, что отправляем JSON (если есть тело запроса)
ЗаголовокЗапроса.Вставить("Content-Type", "application/json"); 

HTTPЗапрос = Новый HTTPЗапрос(Ресурс, ЗаголовокЗапроса);

Важный нюанс: Многие ошибочно устанавливают только Content-Type, забывая про Accept. Если сервер по умолчанию настроен на выдачу XML, без заголовка Accept вы продолжите получать ошибки парсинга.

Решение 2: Обработка пагинации и курсоров (next-page-token)

Часто возникает ситуация, когда первая порция данных (например, первые 100 товаров) обрабатывается успешно, а на следующей странице снова возникает ошибка. Выясним причину этого поведения.

В API Яндекса используется механизм токенов для постраничного вывода. Когда мы запрашиваем следующую страницу, мы создаем новый HTTPЗапрос. Типичная ошибка программиста — не продублировать заголовки Accept и Content-Type во втором и последующих запросах. В этом случае сервер «забывает», что вы работали с JSON, и возвращает следующую порцию данных в формате по умолчанию (XML).

Проанализируем алгоритм работы с токеном:


// В цикле получения страниц
Пока ЗначениеЗаполнено(ТекущийТокен) Цикл
    ЗапросСледующейСтраницы = Новый HTTPЗапрос(ПутьСПараметромТокена);
    // ОБЯЗАТЕЛЬНО добавляем заголовки повторно!
    ЗапросСледующейСтраницы.Заголовки.Вставить("Accept", "application/json");
    
    Ответ = Соединение.ВызватьHTTPМетод("GET", ЗапросСледующейСтраницы);
    // ... обработка ответа
КонецЦикла;

Решение 3: Очистка невидимых символов и BOM

Если вы убедились, что ответ приходит в формате JSON (строка начинается с {), но ошибка «Непредвиденный символ» сохраняется на первой же позиции, скорее всего, в начале строки присутствует BOM (Byte Order Mark) — невидимый маркер кодировки UTF-8.

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


ТелоСтрокой = HTTPОтвет.ПолучитьТелоКакСтроку();

// Удаляем BOM (символ с кодом 65279), если он есть
СимволBOM = Символ(65279);
Пока Лев(ТелоСтрокой, 1) = СимволBOM Цикл
    ТелоСтрокой = Сред(ТелоСтрокой, 2);
КонецЦикла;

// Дополнительно можно обрезать лишние пробелы по краям
ТелоСтрокой = СокрЛП(ТелоСтрокой);

ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ТелоСтрокой);

Также следует помнить, что в описаниях товаров (которые хранит Яндекс) могут встречаться неэкранированные управляющие символы (например, «битые» переносы строк с ASCII-кодами ниже 32). Если такие символы попадают внутрь JSON-строки, парсер 1С может их не пропустить. В этом случае полезно проанализировать тело ответа в текстовом редакторе, поддерживающем отображение невидимых символов (например, Notepad++ или VS Code).

Практические советы по отладке

Чтобы быстро найти проблемное место в большом объеме данных, выполните следующие шаги:

  1. Сохранение в файл: Вместо попытки сразу прочитать JSON, сохраните HTTPОтвет.ПолучитьТелоКакДвоичныеДанные() в файл на диске. Это позволит вам изучить «сырые» данные без искажений со стороны отладчика 1С.
  2. Использование пошагового чтения: Вместо функции ПрочитатьJSON(ЧтениеJSON), которая читает весь объект целиком, используйте цикл с методом ЧтениеJSON.Прочитать(). Это позволит вам увидеть, на каком именно товаре или свойстве парсер «споткнулся».
  3. Проверка соответствия: При вызове ПрочитатьJSON вторым параметром рекомендуется передавать Истина (читать в соответствие). Это делает структуру данных более предсказуемой при работе с динамическими ключами, которые могут встречаться в API маркетплейсов.

Подводя итог, можно сказать, что интеграция с Яндекс.Маркетом требует строгого соблюдения протокола HTTP. Правильная установка заголовка Accept: application/json и внимательное отношение к повторным запросам при пагинации — залог стабильной работы вашего кода и отсутствия ошибок «непредвиденного символа».

← На главную