При интеграции 1С со сторонними веб-сервисами и REST API частой задачей является отправка запроса и разбор полученного ответа в формате JSON. Начинающие разработчики нередко сталкиваются с ошибками при передаче параметров в объект ЧтениеJSON, пытаясь передать туда URL-адрес вместо потока данных, сохраняют файлы на диск или получают ошибки перенаправления HTTP 301 Moved Permanently из-за неверной настройки протокола HTTPS.
Разберем подробно, как правильно настроить соединение с сервером, отправить запрос, обработать возможные редиректы и распарсить 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С.
Если объем передаваемых данных небольшой (до нескольких мегабайт), проще и нагляднее получить тело ответа в виде обычной строки и передать её в метод УстановитьСтроку() объекта Чтение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.Закрыть();
КонецЕсли;
Проанализируем частую ситуацию: в браузере запрос открывается корректно, а в 1С возвращается ответ с кодом 301 или 302 и HTML-страницей с текстом о перемещении ресурса.
HTTPСоединение без параметра ЗащищенноеСоединениеOpenSSL на 80-й порт, веб-сервер выдаст 301 редирект на защищенный адрес. Решение: обязательно указывать порт 443 и передавать объект Новый ЗащищенноеСоединениеOpenSSL() в 7-й параметр конструктора HTTPСоединение.HTTPСоединение нельзя передавать https://mysite.com. Должно быть только доменное имя mysite.com. Префикс протокола вызывает ошибки маршрутизации./api/v1/users/ вместо /api/v1/users). При отсутствии закрывающего слэша сервер отправляет 301 редирект.Объект 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ЗапросПовторный);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если для работы с 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, вы обеспечите быструю, стабильную и безопасную интеграцию без захламления файловой системы временными файлами.