Как получить JSON-данные по ссылке в 1С, если HTTPЗапрос возвращает HTML?

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

Нередко программисты 1С сталкиваются с ситуацией, когда при попытке получить данные с веб-сервиса с помощью объекта HTTPЗапрос мы получаем вместо ожидаемой JSON-структуры какой-то HTML-код. При этом в браузере тот же самый URL прекрасно открывается и показывает требуемый JSON. Мы с вами разберем, почему так происходит и как правильно настроить HTTP-запрос в 1С, чтобы успешно получать и обрабатывать JSON-данные.

Выясняем причину: почему браузер видит JSON, а 1С – HTML?

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

  1. Заголовок Accept: Браузеры, когда отправляют запрос, автоматически добавляют заголовок Accept, который указывает серверу, какие типы контента они готовы принять. Часто в этот список входит application/json, text/html и другие. Сервер, видя, что запрос пришел от браузера и он может отобразить HTML, нередко возвращает отформатированную HTML-страницу для удобного просмотра пользователем. Если же в запросе 1С этот заголовок отсутствует или не содержит application/json, сервер может по умолчанию вернуть text/html.
  2. Заголовок User-Agent: Еще один заголовок, который браузеры отправляют автоматически, это User-Agent. Он содержит информацию о браузере, его версии и операционной системе. Некоторые веб-сервисы могут использовать этот заголовок для более строгой проверки клиента и, если User-Agent не соответствует типичному браузерному, могут изменить свое поведение, например, отдать HTML-страницу вместо JSON.
  3. Авторизация и токен: Многие современные API требуют авторизации. Если в браузере вы уже авторизованы (например, через куки, сессию или токен в локальном хранилище), API может вернуть полные JSON-данные. При этом, если в запросе 1С не передан необходимый токен или другие заголовки авторизации, сервер может вернуть HTML-страницу с ошибкой, предупреждением или даже форму входа, пытаясь вас авторизовать.
  4. Правильное разделение URL: Одной из распространенных ошибок является некорректное разделение базового адреса сервера и пути к ресурсу API. Мы должны четко понимать, что объект HTTPСоединение предназначен для установки соединения с базовым адресом сервера (доменное имя, возможно, с указанием протокола и порта), а объект HTTPЗапрос — для указания относительного пути к конкретному API-методу с параметрами.

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

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

  1. Создаем объект 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, Таймаут);
    
  2. Формируем объект HTTPЗапрос:

    Теперь создадим объект HTTPЗапрос. В его конструктор мы передаем относительный путь к ресурсу API, включая все параметры запроса (query parameters), но без доменного имени сервера. Если у вас есть постоянный базовый путь для API (например, /fundmetrology/eapi/), его также следует включить сюда.

    
    // Пример пути с параметрами
    ПутьКРесурсу = "/fundmetrology/eapi/orders?date=123&date2=234";
    
    Запрос = Новый HTTPЗапрос(ПутьКРесурсу);
    
  3. Устанавливаем необходимые HTTP-заголовки:

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

    1. Заголовок Accept: Запрашиваем JSON.

      Этот заголовок указывает серверу, что мы ожидаем ответ в формате JSON. Это заставит сервер, если он поддерживает этот формат, отдать именно JSON.

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

      Если ваш запрос является, например, POST или PUT и вы отправляете JSON-данные в теле запроса, вам также необходимо указать заголовок Content-Type, чтобы сервер знал, как интерпретировать тело вашего запроса.

      
      // Если вы отправляете JSON-данные в теле POST-запроса
      // Например:
      // ТелоЗапроса = Новый ЗаписьJSON;
      // ТелоЗапроса.ОткрытьДляЗаписи(Новый ЗаписьТекста(Новый ДвоичныеДанные(""), КодировкаТекста.UTF8));
      // ЗаписатьJSON(ТелоЗапроса, СтруктураДанныхДляОтправки);
      // ТелоЗапроса.Закрыть();
      // Запрос.УстановитьТелоИзСтроки(ТелоЗапроса.Закрыть(), КодировкаТекста.UTF8, "application/json");
      
      // Добавляем заголовок Content-Type
      Заголовки.Вставить("Content-Type", "application/json");
      Запрос.УстановитьЗаголовки(Заголовки);
      
    3. Заголовок 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");
      Запрос.УстановитьЗаголовки(Заголовки);
      
    4. Заголовок Authorization (если требуется авторизация):

      Если API требует авторизации (например, с использованием Bearer-токена), мы должны передать этот токен в соответствующем заголовке.

      
      // Если API требует авторизации
      Заголовки.Вставить("Authorization", "Bearer ВашТокенАвторизации");
      Запрос.УстановитьЗаголовки(Заголовки);
      
  4. Выполняем HTTP-метод:

    Теперь, когда HTTPСоединение и HTTPЗапрос настроены, мы можем выполнить сам запрос. Чаще всего для получения данных используется метод GET.

    
    // Если заголовки были установлены ранее через Запрос.УстановитьЗаголовки()
    Ответ = Соединение.ВызватьHTTPМетод("GET", Запрос);
    
    // Или, если заголовки передаются непосредственно в метод
    // Ответ = Соединение.ВызватьHTTPМетод("GET", Запрос, Заголовки);
    
  5. Обрабатываем полученный JSON-ответ:

    После выполнения запроса мы получаем объект 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-данных через поток предпочтительнее.

Альтернативный подход: Отображение страницы через ПолеHTMLДокумента

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

  1. Добавьте на форму элемент ПолеHTMLДокумента:

    В конфигураторе, при создании или изменении формы, добавьте новый элемент типа "Поле HTML документа".

  2. Установите значение или URL для поля:

    Вы можете либо установить текст (полученный HTML или JSON как строку) в это поле, либо передать ему URL, и поле само загрузит содержимое по ссылке.

    
    // Вариант 1: Устанавливаем полученный текст
    // Предполагаем, что 'Ответ' получен от HTTPСоединения и содержит HTML или JSON-строку
    СтрокаОтвета = Ответ.ПолучитьТелоКакСтроку();
    Элементы.ПолеHTMLДокумента.УстановитьТекст(СтрокаОтвета);
    
    // Вариант 2: Устанавливаем URL напрямую (поле само загрузит страницу)
    // Установите полный URL, включая протокол.
    // Это может быть полезно, если страница динамически генерируется в браузере.
    Элементы.ПолеHTMLДокумента.УстановитьURL("https://fgis.gost.ru/fundmetrology/eapi/orders?date=123");
    

    Однако, этот метод не поможет вам программно извлечь данные из JSON, он предназначен только для визуализации.

Инструменты для отладки и анализа запросов

Для успешной работы с веб-сервисами крайне важно уметь анализировать HTTP-запросы и ответы. Мы рекомендуем использовать следующие инструменты:

  1. Инструменты разработчика браузера (F12):

    Это ваш первый и самый важный инструмент. Откройте нужную веб-страницу в браузере, нажмите F12, перейдите на вкладку "Network" (Сеть). Выполните действие, которое приводит к нужному JSON-ответу. Вы увидите все HTTP-запросы, которые выполнил браузер. Кликнув по интересующему запросу, вы сможете проанализировать:

    • Headers (Заголовки): Заголовки запроса (Request Headers) и заголовки ответа (Response Headers) – здесь вы найдете Accept, User-Agent, Authorization и другие критически важные заголовки, которые нужно воспроизвести в 1С.
    • Response (Ответ): Фактическое тело ответа от сервера.
    • Status Code (Код состояния): Код состояния HTTP (например, 200 OK, 404 Not Found, 500 Internal Server Error).

    Анализ этих данных поможет вам точно воспроизвести запрос в 1С.

  2. Postman или аналоги:

    Postman (или схожие инструменты, такие как Insomnia) – это мощное приложение для конструирования, отправки и тестирования HTTP-запросов. Мы можем вручную задавать URL, методы (GET, POST), заголовки, тело запроса и получать структурированные ответы. После того как вы успешно настроите запрос в Postman, его будет легко перевести в код 1С.

  3. Консоли HTTP-запросов для 1С:

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

  4. Wireshark:

    Это более продвинутый инструмент для анализа сетевого трафика на низком уровне. Он может быть полезен в сложных случаях, когда нужно понять взаимодействие на уровне протоколов, но для большинства задач достаточно F12 или Postman.

Важные моменты

При работе с HTTP-запросами в 1С всегда учитывайте следующие аспекты:

  1. Всегда проверяйте КодСостояния ответа от сервера. Успешный ответ обычно имеет код 200. Коды 4xx указывают на ошибки клиента (неверный запрос, отсутствие авторизации), а 5xx – на ошибки сервера.
  2. Обращайте внимание на кодировку ответа. Если вы видите "кракозябры", возможно, проблема в неверно определенной или указанной кодировке при получении тела ответа.
  3. Современные веб-сервисы и API могут использовать различные механизмы защиты (например, CORS, анти-бот системы, сложные схемы авторизации с JWT-токенами). Если простые методы не работают, возможно, API требует более глубокого изучения его документации и реализации более сложной логики взаимодействия.

В заключение, проблема получения HTML вместо JSON в 1С при работе с HTTP-запросами обычно кроется в неправильной настройке HTTP-заголовков и/или некорректном разделении URL для объектов HTTPСоединение и HTTPЗапрос. Используя наши рекомендации и инструменты отладки, вы сможете успешно настроить свои запросы и получать необходимые JSON-данные.

← На главную