Нередко программисты 1С сталкиваются с ситуацией, когда при попытке получить данные с веб-сервиса с помощью объекта HTTPЗапрос мы получаем вместо ожидаемой JSON-структуры какой-то HTML-код. При этом в браузере тот же самый URL прекрасно открывается и показывает требуемый JSON. Мы с вами разберем, почему так происходит и как правильно настроить HTTP-запрос в 1С, чтобы успешно получать и обрабатывать JSON-данные.
Ситуация, когда браузер и 1С получают разные ответы от одного и того же URL, может показаться загадочной, но у нее есть вполне логичные объяснения. Веб-серверы используют HTTP-заголовки для определения типа клиента (браузер, API-клиент, бот) и желаемого формата ответа. Давайте рассмотрим основные причины, по которым это происходит:
Accept: Браузеры, когда отправляют запрос, автоматически добавляют заголовок Accept, который указывает серверу, какие типы контента они готовы принять. Часто в этот список входит application/json, text/html и другие. Сервер, видя, что запрос пришел от браузера и он может отобразить HTML, нередко возвращает отформатированную HTML-страницу для удобного просмотра пользователем. Если же в запросе 1С этот заголовок отсутствует или не содержит application/json, сервер может по умолчанию вернуть text/html.User-Agent: Еще один заголовок, который браузеры отправляют автоматически, это User-Agent. Он содержит информацию о браузере, его версии и операционной системе. Некоторые веб-сервисы могут использовать этот заголовок для более строгой проверки клиента и, если User-Agent не соответствует типичному браузерному, могут изменить свое поведение, например, отдать HTML-страницу вместо JSON.HTTPСоединение предназначен для установки соединения с базовым адресом сервера (доменное имя, возможно, с указанием протокола и порта), а объект HTTPЗапрос — для указания относительного пути к конкретному API-методу с параметрами.Теперь, когда мы понимаем причины, давайте разберем по шагам, как правильно настроить HTTP-запрос в 1С для гарантированного получения JSON-данных.
HTTPСоединение:
Начнем с создания объекта HTTPСоединение. В его конструктор мы должны передать только базовый адрес сервера, без указания конкретного пути к API-методу. Например, если полный URL выглядит как https://api-adress.ru/orders?date=123, то для HTTPСоединение мы используем только api-adress.ru. Если API находится по пути, например, fgis.gost.ru/fundmetrology/eapi/, то частью для HTTPСоединение будет fgis.gost.ru, а /fundmetrology/eapi/ будет уже частью пути для HTTPЗапрос. Важно также учитывать использование протокола HTTPS, указывая соответствующий параметр в конструкторе.
// Пример для HTTPS
ИмяСервера = "fgis.gost.ru"; // Или "api-adress.ru"
Порт = 443; // Стандартный порт для HTTPS
SSL = Истина; // Используем защищенное соединение
Таймаут = 10; // Таймаут в секундах
Соединение = Новый HTTPСоединение(ИмяСервера, Порт, , , SSL, Таймаут);
HTTPЗапрос:
Теперь создадим объект HTTPЗапрос. В его конструктор мы передаем относительный путь к ресурсу API, включая все параметры запроса (query parameters), но без доменного имени сервера. Если у вас есть постоянный базовый путь для API (например, /fundmetrology/eapi/), его также следует включить сюда.
// Пример пути с параметрами
ПутьКРесурсу = "/fundmetrology/eapi/orders?date=123&date2=234";
Запрос = Новый HTTPЗапрос(ПутьКРесурсу);
Это критически важный шаг, который зачастую является причиной получения HTML вместо JSON. Мы должны явно сообщить серверу, какой формат данных мы хотим получить и, при необходимости, предоставить данные для авторизации.
Accept: Запрашиваем JSON.
Этот заголовок указывает серверу, что мы ожидаем ответ в формате JSON. Это заставит сервер, если он поддерживает этот формат, отдать именно JSON.
Заголовки = Новый Соответствие();
Заголовки.Вставить("Accept", "application/json"); // Просим JSON-ответ
Запрос.УстановитьЗаголовки(Заголовки);
Content-Type (если отправляем данные):
Если ваш запрос является, например, POST или PUT и вы отправляете JSON-данные в теле запроса, вам также необходимо указать заголовок Content-Type, чтобы сервер знал, как интерпретировать тело вашего запроса.
// Если вы отправляете JSON-данные в теле POST-запроса
// Например:
// ТелоЗапроса = Новый ЗаписьJSON;
// ТелоЗапроса.ОткрытьДляЗаписи(Новый ЗаписьТекста(Новый ДвоичныеДанные(""), КодировкаТекста.UTF8));
// ЗаписатьJSON(ТелоЗапроса, СтруктураДанныхДляОтправки);
// ТелоЗапроса.Закрыть();
// Запрос.УстановитьТелоИзСтроки(ТелоЗапроса.Закрыть(), КодировкаТекста.UTF8, "application/json");
// Добавляем заголовок Content-Type
Заголовки.Вставить("Content-Type", "application/json");
Запрос.УстановитьЗаголовки(Заголовки);
User-Agent (опционально, для имитации браузера):
В некоторых случаях, если сервер очень "капризный", может потребоваться имитировать запрос от реального браузера, добавив соответствующий User-Agent. Вы можете скопировать его из инструментов разработчика своего браузера (вкладка Network -> Headers).
Заголовки.Вставить("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36");
Запрос.УстановитьЗаголовки(Заголовки);
Authorization (если требуется авторизация):
Если API требует авторизации (например, с использованием Bearer-токена), мы должны передать этот токен в соответствующем заголовке.
// Если API требует авторизации
Заголовки.Вставить("Authorization", "Bearer ВашТокенАвторизации");
Запрос.УстановитьЗаголовки(Заголовки);
Теперь, когда HTTPСоединение и HTTPЗапрос настроены, мы можем выполнить сам запрос. Чаще всего для получения данных используется метод GET.
// Если заголовки были установлены ранее через Запрос.УстановитьЗаголовки()
Ответ = Соединение.ВызватьHTTPМетод("GET", Запрос);
// Или, если заголовки передаются непосредственно в метод
// Ответ = Соединение.ВызватьHTTPМетод("GET", Запрос, Заголовки);
После выполнения запроса мы получаем объект HTTPОтвет. Прежде всего, мы должны проверить КодСостояния ответа, чтобы убедиться, что запрос был успешным (обычно 200 OK).
Для чтения JSON-данных рекомендуется использовать Ответ.ПолучитьТелоКакПоток() в сочетании с объектами ЧтениеJSON и функцией ПрочитатьJSON(). Этот подход более эффективен, особенно для больших объемов данных, и лучше справляется с кодировками.
Если Ответ.КодСостояния = 200 Тогда // Проверяем успешность ответа
Поток = Ответ.ПолучитьТелоКакПоток();
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.ОткрытьПоток(Поток);
МассивДанных = ПрочитатьJSON(ЧтениеJSON); // МассивДанных будет содержать разобранные JSON-данные
ЧтениеJSON.Закрыть();
// Теперь МассивДанных содержит ваши данные в виде Структуры, Массива или их комбинации.
// Вы можете сохранить эти данные в файл, обработать их или вывести на экран.
// Пример сохранения полученного JSON в файл:
ИмяФайлаJSON = КаталогВременныхФайлов() + "response.json";
ЗаписьТекста = Новый ЗаписьТекста(ИмяФайлаJSON, КодировкаТекста.UTF8);
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ОткрытьДляЗаписи(ЗаписьТекста);
ЗаписатьJSON(ЗаписьJSON, МассивДанных); // Записываем разобранные данные обратно в JSON-формат
ЗаписьJSON.Закрыть();
ЗаписьТекста.Закрыть();
Сообщить("JSON-данные успешно получены и сохранены в файл: " + ИмяФайлаJSON);
Иначе
// Если произошла ошибка, выводим код состояния и тело ответа для анализа
Сообщить("Ошибка при получении данных. Код состояния: " + Ответ.КодСостояния);
Сообщить("Тело ответа: " + Ответ.ПолучитьТелоКакСтроку());
КонецЕсли;
Важно отметить, что ПолучитьТелоКакСтроку() также может использоваться, но для JSON-данных через поток предпочтительнее.
Если ваша основная задача — не программный парсинг JSON, а просто отображение содержимого веб-страницы (которая в браузере показывается как отформатированный JSON, или содержит HTML), вы можете воспользоваться элементом формы ПолеHTMLДокумента. Этот подход позволяет встроить браузерную функциональность прямо в форму 1С.
ПолеHTMLДокумента:
В конфигураторе, при создании или изменении формы, добавьте новый элемент типа "Поле HTML документа".
Вы можете либо установить текст (полученный HTML или JSON как строку) в это поле, либо передать ему URL, и поле само загрузит содержимое по ссылке.
// Вариант 1: Устанавливаем полученный текст
// Предполагаем, что 'Ответ' получен от HTTPСоединения и содержит HTML или JSON-строку
СтрокаОтвета = Ответ.ПолучитьТелоКакСтроку();
Элементы.ПолеHTMLДокумента.УстановитьТекст(СтрокаОтвета);
// Вариант 2: Устанавливаем URL напрямую (поле само загрузит страницу)
// Установите полный URL, включая протокол.
// Это может быть полезно, если страница динамически генерируется в браузере.
Элементы.ПолеHTMLДокумента.УстановитьURL("https://fgis.gost.ru/fundmetrology/eapi/orders?date=123");
Однако, этот метод не поможет вам программно извлечь данные из JSON, он предназначен только для визуализации.
Для успешной работы с веб-сервисами крайне важно уметь анализировать HTTP-запросы и ответы. Мы рекомендуем использовать следующие инструменты:
Это ваш первый и самый важный инструмент. Откройте нужную веб-страницу в браузере, нажмите F12, перейдите на вкладку "Network" (Сеть). Выполните действие, которое приводит к нужному JSON-ответу. Вы увидите все HTTP-запросы, которые выполнил браузер. Кликнув по интересующему запросу, вы сможете проанализировать:
Accept, User-Agent, Authorization и другие критически важные заголовки, которые нужно воспроизвести в 1С.Анализ этих данных поможет вам точно воспроизвести запрос в 1С.
Postman (или схожие инструменты, такие как Insomnia) – это мощное приложение для конструирования, отправки и тестирования HTTP-запросов. Мы можем вручную задавать URL, методы (GET, POST), заголовки, тело запроса и получать структурированные ответы. После того как вы успешно настроите запрос в Postman, его будет легко перевести в код 1С.
Существуют внешние обработки и расширения для 1С, которые предоставляют графический интерфейс для создания HTTP-запросов и генерации кода. Это может быть удобным инструментом для быстрого тестирования.
Это более продвинутый инструмент для анализа сетевого трафика на низком уровне. Он может быть полезен в сложных случаях, когда нужно понять взаимодействие на уровне протоколов, но для большинства задач достаточно F12 или Postman.
При работе с HTTP-запросами в 1С всегда учитывайте следующие аспекты:
КодСостояния ответа от сервера. Успешный ответ обычно имеет код 200. Коды 4xx указывают на ошибки клиента (неверный запрос, отсутствие авторизации), а 5xx – на ошибки сервера.В заключение, проблема получения HTML вместо JSON в 1С при работе с HTTP-запросами обычно кроется в неправильной настройке HTTP-заголовков и/или некорректном разделении URL для объектов HTTPСоединение и HTTPЗапрос. Используя наши рекомендации и инструменты отладки, вы сможете успешно настроить свои запросы и получать необходимые JSON-данные.