Как в 1С отправить HTTP-запрос и прочитать ответ в формате JSON без сохранения во временный файл?

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

При интеграции 1С со сторонними веб-сервисами и REST API частой задачей является отправка запроса и разбор полученного ответа в формате JSON. Начинающие разработчики нередко сталкиваются с ошибками при передаче параметров в объект ЧтениеJSON, пытаясь передать туда URL-адрес вместо потока данных, сохраняют файлы на диск или получают ошибки перенаправления HTTP 301 Moved Permanently из-за неверной настройки протокола HTTPS.

Разберем подробно, как правильно настроить соединение с сервером, отправить запрос, обработать возможные редиректы и распарсить JSON прямо в оперативной памяти без создания промежуточных файлов.

Способ 1. Чтение JSON через поток данных (ПолучитьТелоКакПоток)

Метод ЧтениеJSON.ОткрытьПоток() ожидает в качестве первого параметра объект типа Поток. Получить его можно напрямую из ответа сервера с помощью метода HTTPОтвет.ПолучитьТелоКакПоток(). Это наиболее производительный вариант при работе с большими объемами данных, так как платформа считывает данные порциями.

Рассмотрим пример создания защищенного подключения и чтения данных через поток:


// 1. Указываем хост без префиксов http:// или https://
ИмяСервера = "api.mysite.com";
ПутьКРесурсу = "/v1/data/get";

// 2. Инициализируем защищенное соединение для протокола HTTPS (порт 443)
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение(ИмяСервера, 443, , , , 30, ЗащищенноеСоединение);

// 3. Формируем и отправляем запрос
HTTPЗапрос = Новый HTTPЗапрос(ПутьКРесурсу);
HTTPЗапрос.Заголовки.Вставить("Accept", "application/json");

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

Если HTTPОтвет.КодСостояния = 200 Тогда
    // 4. Открываем поток и читаем JSON (кодировка по стандарту RFC 8259 — UTF-8)
    ПотокОтвета = HTTPОтвет.ПолучитьТелоКакПоток();
    
    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.ОткрытьПоток(ПотокОтвета, "UTF-8");
    
    // Считываем JSON в Структуру или Соответствие
    Данные = ПрочитатьJSON(ЧтениеJSON, Истина);
    ЧтениеJSON.Закрыть();
    
    // Обрабатываем полученные данные
    Сообщить("Данные успешно прочитаны!");
Иначе
    Сообщить("Ошибка при обращении к серверу. Код ответа: " + HTTPОтвет.КодСостояния);
КонецЕсли;

Важный момент: передача второго параметра Истина в функцию ПрочитатьJSON(ЧтениеJSON, Истина) предписывает платформе считывать объекты JSON в виде коллекции Соответствие, а не Структура. Это защитит обработку от аварийного завершения, если в JSON встретятся ключи с дефисами, пробелами или начинающиеся с цифр, которые недопустимы в качестве имен свойств структуры 1С.

Способ 2. Разбор JSON через строковую переменную (ПолучитьТелоКакСтроку)

Если объем передаваемых данных небольшой (до нескольких мегабайт), проще и нагляднее получить тело ответа в виде обычной строки и передать её в метод УстановитьСтроку() объекта ЧтениеJSON.

Посмотрим на практическую реализацию этого метода:


ИмяСервера = "api.mysite.com";
ПутьКРесурсу = "/v1/catalog";

ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение(ИмяСервера, 443, , , , 30, ЗащищенноеСоединение);

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

Если HTTPОтвет.КодСостояния = 200 Тогда
    СтрокаJSON = HTTPОтвет.ПолучитьТелоКакСтроку();
    
    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.УстановитьСтроку(СтрокаJSON);
    
    Данные = ПрочитатьJSON(ЧтениеJSON);
    ЧтениеJSON.Закрыть();
КонецЕсли;

Причины возникновения ошибки 301 Moved Permanently и их устранение

Проанализируем частую ситуацию: в браузере запрос открывается корректно, а в 1С возвращается ответ с кодом 301 или 302 и HTML-страницей с текстом о перемещении ресурса.

  1. Перенаправление с HTTP на HTTPS. Браузеры делают перенаправление незаметно для пользователя. Если в 1С создать HTTPСоединение без параметра ЗащищенноеСоединениеOpenSSL на 80-й порт, веб-сервер выдаст 301 редирект на защищенный адрес. Решение: обязательно указывать порт 443 и передавать объект Новый ЗащищенноеСоединениеOpenSSL() в 7-й параметр конструктора HTTPСоединение.
  2. Протокол в имени сервера. В конструктор HTTPСоединение нельзя передавать https://mysite.com. Должно быть только доменное имя mysite.com. Префикс протокола вызывает ошибки маршрутизации.
  3. Отсутствие слеша в конце URL. Многие API требуют строгой адресации (например, /api/v1/users/ вместо /api/v1/users). При отсутствии закрывающего слэша сервер отправляет 301 редирект.

Ручная обработка редиректов (301, 302, 307, 308)

Объект HTTPСоединение в платформе 1С не переходит по перенаправлениям автоматически. Если API штатно возвращает адрес перенаправления, его необходимо обработать вручную, извлекая заголовок Location.

Разберем типовой алгоритм обработки редиректа:


ИмяСервера = "api.mysite.com";
ПутьКРесурсу = "/api/v1/resource";

ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение(ИмяСервера, 443, , , , 30, ЗащищенноеСоединение);

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

// Проверяем статус перенаправления
Если HTTPОтвет.КодСостояния = 301 Или HTTPОтвет.КодСостояния = 302 Тогда
    НовыйАдрес = "";
    
    // В заголовках ключ Location может быть в разном регистре
    Для Каждого Заголовок Из HTTPОтвет.Заголовки Цикл
        Если ВРег(Заголовок.Ключ) = "LOCATION" Тогда
            НовыйАдрес = Заголовок.Значение;
            Прервать;
        КонецЕсли;
    КонецЦикла;
    
    Если ЗначениеЗаполнено(НовыйАдрес) Тогда
        // Если перенаправление на относительный путь того же сервера
        Если Лев(НовыйАдрес, 1) = "/" Тогда
            HTTPЗапросПовторный = Новый HTTPЗапрос(НовыйАдрес);
            HTTPОтвет = Соединение.Получить(HTTPЗапросПовторный);
        КонецЕсли;
    КонецЕсли;
КонецЕсли;

Передача Cookie и дополнительных заголовков

Если для работы с API (например, amoCRM или другими сервисами) требуется авторизация по cookie или передача нестандартных параметров (аналог опций cURL), их следует явно добавлять в коллекцию HTTPЗапрос.Заголовки:


HTTPЗапрос = Новый HTTPЗапрос(ПутьКРесурсу);
HTTPЗапрос.Заголовки.Вставить("User-Agent", "1C-Integration-Client/1.0");
HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");

// Передача авторизационных куки
HTTPЗапрос.Заголовки.Вставить("Cookie", "session_id=abcdef123456; domain=.mysite.com");

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

Используя прямое чтение из потока или строки в сочетании с корректной инициализацией ЗащищенноеСоединениеOpenSSL, вы обеспечите быструю, стабильную и безопасную интеграцию без захламления файловой системы временными файлами.

← На главную