К статье
Практический материал

Разработка и Конфигурация · 13 мин

Как разобрать HTTP-ответ в 1С: разбор кода, заголовков и тела ответа

Практическое руководство по разбору HTTP-ответа в 1С: чтение кода состояния, заголовков, тела ответа, парсинг JSON и обработка ошибок с примерами кода.

При обмене данными с внешними сервисами — банками, маркетплейсами, курьерскими службами, внутренними API — разработчик 1С получает HTTP-ответ и должен корректно его интерпретировать: понять, успешен ли запрос, что вернул сервер и как извлечь нужные данные. Ошибка на этом этапе приводит либо к падению обработки, либо к тихой потере данных, что гораздо опаснее.

Объект HTTPОтвет в платформе 1С содержит три ключевые части: код состояния (число вроде 200, 404, 500), коллекцию заголовков и тело ответа — строку, поток или двоичные данные. Каждая часть разбирается своими методами, и у каждой есть типичные подводные камни: кодировки, перенаправления, сжатие, нестандартные ответы сервера.

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

Как выполнить запрос и получить объект ответа

Разбор начинается с корректного выполнения запроса. Создаётся соединение HTTPСоединение, формируется HTTPЗапрос с указанием ресурса и заголовков, затем вызывается один из методов: Получить() (GET), ОтправитьДляОбработки() (POST), Записать() (PUT) или Удалить() (DELETE).

Типовой каркас выглядит так:

Соединение = Новый HTTPСоединение("api.example.ru", 443, , , , 30,

Новый ЗащищенноеСоединениеOpenSSL);

Запрос = Новый HTTPЗапрос("/v1/orders?date=2026-01-01");

Запрос.Заголовки.Вставить("Accept", "application/json");

Запрос.Заголовки.Вставить("Authorization", "Bearer " + Токен);

Ответ = Соединение.Получить(Запрос);

Обратите внимание на таймаут (в примере — 30 секунд). Без него при недоступном сервере фоновое задание или сеанс пользователя зависнет надолго. Для интерактивных операций разумно ставить таймаут меньше, для обмена большими файлами — больше.

Результат вызова — объект HTTPОтвет, с которым и идёт дальнейшая работа. Важно: сам вызов метода не бросает исключение при кодах 4xx и 5xx — сервер ответил, и платформа считает обмен успешным. Проверка кода состояния — обязанность разработчика.

Как проверить код состояния ответа

Свойство КодСостояния возвращает целое число. Первое, что нужно сделать после получения ответа, — классифицировать этот код, а не сразу лезть в тело.

ДиапазонЗначениеДействие в 1С
200–299Успех: 200 OK, 201 Created, 204 No ContentРазбирать тело (для 204 тела может не быть)
301, 302, 307ПеренаправлениеПроверить заголовок Location, повторить запрос по новому адресу
400, 422Ошибка в данных запросаРазобрать тело — сервер часто пишет причину
401, 403Нет авторизации или правПроверить токен, ключ, срок его действия
404Ресурс не найденПроверить URL и параметры
429Превышен лимит запросовПодождать и повторить с паузой
500–599Ошибка на стороне сервераПовторить позже, залогировать тело ответа

Пример проверки:

Если Ответ.КодСостояния >= 200 И Ответ.КодСостояния < 300 Тогда

// разбор тела

ИначеЕсли Ответ.КодСостояния = 401 Тогда

ВызватьИсключение "Ошибка авторизации: проверьте токен доступа";

Иначе

ВызватьИсключение СтрШаблон("Сервер вернул код %1: %2",

Ответ.КодСостояния,

Лев(Ответ.ПолучитьТелоКакСтроку(), 500));

КонецЕсли;

Как прочитать и разобрать заголовки ответа

Заголовки хранятся в свойстве Заголовки — это соответствие, где ключи регистронезависимы. Чаще всего из заголовков нужны тип содержимого, кодировка и служебные поля вроде Location или Retry-After.

ТипСодержимого = Ответ.Заголовки.Получить("Content-Type");

// например: "application/json; charset=utf-8"

Если ТипСодержимого <> Неопределено

И СтрНайти(НРег(ТипСодержимого), "application/json") > 0 Тогда

// безопасно разбирать как JSON

КонецЕсли;

Проверка Content-Type перед разбором тела — хорошая практика. Если сервер вместо JSON вернул HTML-страницу ошибки (так делают прокси и балансировщики при сбоях), попытка прочитать её как JSON выдаст невразумительное исключение. Предварительная проверка типа позволяет сразу выдать понятное сообщение.

Отдельный случай — перенаправления. Платформа 1С не всегда автоматически следует редиректам, поэтому при кодах 301/302/307 нужно самостоятельно взять заголовок Location и выполнить новый запрос. Следите, чтобы цикл перенаправлений не был бесконечным — ограничьте число переходов, например, пятью.

Как получить тело ответа: строка, поток, двоичные данные

Платформа предлагает три метода чтения тела, и выбор зависит от характера данных:

  • ПолучитьТелоКакСтроку() — для текстовых ответов: JSON, XML, HTML, CSV. Метод сам определяет кодировку по заголовку Content-Type, при необходимости кодировку можно передать параметром.
  • ПолучитьТелоКакДвоичныеДанные() — для файлов: картинок, PDF, архивов. Дальше данные записываются через Записать() в файл или помещаются во временное хранилище.
  • ПолучитьТелоКакПоток() — для больших ответов, когда нежелательно загружать всё в память. Поток можно построчно читать или перенаправить в файл.

Для больших файлов есть более удобная альтернатива: метод соединения Получить(Запрос, ИмяФайлаРезультата) сразу пишет тело в файл на диске, минуя память сервера 1С. Это заметно снижает риск нехватки памяти при скачивании отчётов и выгрузок объёмом в сотни мегабайт.

Частая проблема со строковым чтением — «кракозябры» вместо кириллицы. Причина почти всегда в том, что сервер не указал кодировку в заголовке, а платформа приняла тело за Latin-1. Решение — явно передать кодировку: Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8).

Маршрут решения

Как выбрать способ чтения тела

Ответ — JSON, XML или другой текст разумного размераИспользуйте ПолучитьТелоКакСтроку() с явным указанием UTF-8 при проблемах с кодировкой
Ответ — файл (PDF, изображение, архив)Используйте ПолучитьТелоКакДвоичныеДанные() или запись напрямую в файл через параметр метода Получить()
Ответ очень большой и память ограниченаЧитайте через ПолучитьТелоКакПоток() или сохраняйте сразу в файл
Нужно и показать тело в журнале, и разобратьСохраните строку в переменную один раз и дальше работайте с ней

Как разобрать JSON из тела ответа

Большинство современных API возвращают JSON. В 1С для разбора используется объект ЧтениеJSON в связке с ПрочитатьJSON:

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

Чтение = Новый ЧтениеJSON;

Чтение.УстановитьСтроку(ТекстОтвета);

Данные = ПрочитатьJSON(Чтение); // Соответствие или Массив

Чтение.Закрыть();

Для Каждого Заказ Из Данные["orders"] Цикл

НомерЗаказа = Заказ["number"];

Сумма = Заказ["total"];

КонецЦикла;

По умолчанию ПрочитатьJSON возвращает Соответствие. Если нужны привычные обращения через точку (Данные.orders вместо Данные["orders"]), передайте вторым параметром Истина — тогда результат будет структурой. Но помните: имена ключей JSON с дефисами или начинающиеся с цифры в структуру не преобразуются корректно.

Даты в JSON приходят строками. Их можно преобразовать автоматически, указав в ПрочитатьJSON параметр с именами полей дат и форматом ФорматДатыJSON.ISO, либо разбирать вручную через ПрочитатьДатуJSON(). Ручной вариант надёжнее, когда сервер присылает даты в нестандартном виде.

Всегда проверяйте существование ключей перед обращением: Если Данные.Получить("orders") <> Неопределено Тогда .... Структура ответа внешнего API может меняться без предупреждения, и обращение к отсутствующему ключу у соответствия вернёт Неопределено, а у структуры — вызовет исключение.

bsl
Функция РазобратьОтветJSON(Ответ)
    Если Ответ.КодСостояния < 200 ИЛИ Ответ.КодСостояния >= 300 Тогда
        ВызватьИсключение СтрШаблон("HTTP %1", Ответ.КодСостояния);
    КонецЕсли;
    Текст = Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
    Чтение = Новый ЧтениеJSON;
    Чтение.УстановитьСтроку(Текст);
    Результат = ПрочитатьJSON(Чтение);
    Чтение.Закрыть();
    Возврат Результат;
КонецФункции

Как обработать ошибки и нестандартные ситуации

Помимо кодов ошибок сервера, встречаются сбои на уровне соединения: таймаут, разрыв SSL, недоступность хоста. Такие ситуации вызывают исключение платформы ещё на этапе вызова метода, поэтому весь обмен стоит оборачивать в Попытка ... Исключение ... КонецПопытки с записью подробностей в журнал регистрации.

Попытка

Ответ = Соединение.Получить(Запрос);

Исключение

ЗаписьЖурналаРегистрации("Обмен с API",

УровеньЖурналаРегистрации.Ошибка, , ,

ОписаниеОшибки());

ВызватьИсключение "Сервис недоступен, попробуйте позже";

КонецПопытки;

Ещё одна нестандартная ситуация — пустое тело при успешном коде. Код 204 No Content штатно означает отсутствие тела, и попытка прочитать из него JSON закончится ошибкой. Проверяйте длину строки перед разбором.

Некоторые серверы сжимают ответы gzip. Если в запросе вы сами не ставили заголовок Accept-Encoding: gzip, сервер обычно отвечает несжатым текстом. Если сжатие всё же используется, тело нужно распаковать — например, через объекты работы с zip-потоками или отказавшись от запроса сжатия.

Типичные ошибки
01
Разбор тела без проверки КодСостояния — при ошибке сервера обработка падает с невнятным сообщением или молча записывает мусор в данные
02
Обращение к ключу соответствия без проверки его существования — при изменении структуры API получаете Неопределено и неявные сбои дальше по коду
03
Чтение тела как строки без указания кодировки — кириллица превращается в нечитаемые символы
04
Отсутствие таймаута у HTTPСоединения — при недоступном сервере зависает сеанс пользователя или фоновое задание
05
Повторное чтение тела из того же объекта ответа — второй вызов возвращает пустую строку
06
Игнорирование редиректов — запрос уходит на старый адрес, а ответ 302 ошибочно считается результатом

Как проверить результат и залогировать обмен

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

При отладке удобно выводить ответ целиком во временный файл и открывать его в текстовом редакторе с подсветкой JSON — так структура видна нагляднее, чем в сообщении или журнале регистрации. Не оставляйте такой отладочный вывод в рабочем коде без ограничений: тела ответов могут содержать персональные данные и токены.

Контрольные точки

Как проверить результат

Код состояния ответа
Норма

Значение в диапазоне 200–299

Тревожный признак

4xx или 5xx — запрос не выполнен, тело разбирать нельзя без анализа причины

Заголовок Content-Type
Норма

Соответствует ожидаемому формату, например application/json

Тревожный признак

text/html при ожидании JSON — вероятно, ошибка прокси или неправильный URL

Тело ответа
Норма

Валидный JSON, нужные ключи присутствуют

Тревожный признак

Пустая строка, кракозябры или HTML-страница ошибки

Загруженные данные
Норма

Количество и содержимое записей совпадает с данными в системе-источнике

Тревожный признак

Пропущены записи, даты или суммы сдвинуты — проверяйте формат и часовой пояс

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

Итог

Что важно запомнить

Разбор HTTP-ответа в 1С строится вокруг трёх шагов: проверка КодСостояния, чтение Заголовков и извлечение тела подходящим методом. JSON разбирается через ЧтениеJSON и ПрочитатьJSON с обязательной проверкой существования ключей. Таймаут соединения, обработка исключений и логирование — обязательный минимум для производственного обмена.

Частые вопросы

Чем отличается ПолучитьТелоКакСтроку() от ПолучитьТелоКакДвоичныеДанные()?

Первый метод интерпретирует тело как текст с учётом кодировки и подходит для JSON, XML, HTML. Второй возвращает сырые байты и нужен для файлов — изображений, PDF, архивов. Если прочитать бинарный файл как строку, данные будут безвозвратно испорчены при перекодировании.

Почему ПрочитатьJSON выдаёт ошибку, хотя сервер ответил успешно?

Чаще всего причины три: тело пустое (код 204), сервер вернул не JSON, а HTML-страницу или текст ошибки, либо в начале строки стоит BOM или лишние символы. Выведите первые 200–300 символов тела в журнал — причина обычно видна сразу.

Как автоматически преобразовать даты из JSON?

Передайте в ПрочитатьJSON параметры: имена полей с датами (строкой через запятую или массивом) и формат ФорматДатыJSON.ISO. Тогда указанные поля сразу станут значениями типа Дата. Поля, не попавшие в список, останутся строками и потребуют ручного разбора.

Сервер возвращает 401, хотя токен правильный. Что проверить?

Убедитесь, что токен передаётся именно в том заголовке и формате, который ждёт API (например, «Bearer » с пробелом перед токеном), что токен не истёк и что в запросе нет лишних пробелов или переводов строк. Также проверьте, не перехватывает ли запрос прокси, требующий собственной авторизации.

Как скачать большой файл, не загружая его в память?

Передайте вторым параметром метода Получить() путь к файлу на диске: Соединение.Получить(Запрос, "C:\Temp\report.zip"). Платформа запишет тело напрямую в файл. После скачивания проверьте код состояния — файл создаётся даже при ошибочном ответе, и в нём может оказаться текст ошибки вместо данных.

Нужно ли закрывать HTTPСоединение после запроса?

Явного метода закрытия у HTTPСоединения нет — соединение освобождается при уничтожении объекта. Однако если выполняется много запросов подряд к одному серверу, выгоднее создать соединение один раз и переиспользовать его, чем открывать заново на каждый запрос.