В современной разработке на платформе 1С:Предприятие 8.3 все чаще приходится сталкиваться с необходимостью интеграции с внешними сайтами и API. Одной из типовых задач является получение изображений товаров. Если раньше многие сайты работали по незащищенному протоколу HTTP, то сегодня повсеместным стандартом стал HTTPS. Это накладывает определенные требования к коду 1С, так как простые методы копирования файлов могут выдавать ошибки доступа или проверки сертификатов.
В этой статье мы подробно разберем, как правильно организовать скачивание картинок по защищенному соединению, рассмотрим основные ошибки и выясним, какой метод является наиболее универсальным.
Наиболее правильным и гибким способом работы с HTTPS является использование объекта HTTPСоединение в сочетании с ЗащищенноеСоединениеOpenSSL. Этот метод позволяет не только скачивать файлы, но и управлять заголовками запроса, обрабатывать коды ответов сервера и настраивать параметры безопасности.
Рассмотрим ситуацию: нам нужно получить ссылку на картинку из JSON-ответа API (например, Sima-land) и затем сохранить саму картинку на диск. Разберем по шагам, как это реализовать.
Шаг 1. Настройка защищенного соединения. Для работы с HTTPS необходимо создать объект, который будет отвечать за проверку сертификатов сервера. В простейшем случае, если мы доверяем системному хранилищу сертификатов Windows, код будет выглядеть так:
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
Шаг 2. Создание соединения и получение данных. Проанализируем пример кода, который выполняет GET-запрос к серверу и сохраняет результат в виде двоичных данных. Обратите внимание, что адрес сервера указывается без префикса "https://", так как использование защищенного соединения уже подразумевает этот протокол.
// Определяем параметры сервера и путь к файлу
Сервер = "cdn3.static1-sima-land.com";
ПутьНаСервере = "/items/4549085/0/700.jpg?v=1600705892";
ПутьКЛокальномуФайлу = "D:\Files\image.jpg";
// Создаем защищенное соединение
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
// Инициализируем HTTPСоединение
// Параметры: Сервер, Порт (443 для https), Логин, Пароль, Прокси, Таймаут, ЗащищенноеСоединение
Соединение = Новый HTTPСоединение(Сервер,,,,,, ЗащищенноеСоединение);
// Формируем запрос
Запрос = Новый HTTPЗапрос(ПутьНаСервере);
Попытка
// Отправляем запрос методом GET
Ответ = Соединение.Получить(Запрос);
Если Ответ.КодСостояния = 200 Тогда
// Получаем тело ответа как двоичные данные
ДвоичныеДанные = Ответ.ПолучитьТелоКакДвоичныеДанные();
// Сохраняем на диск
ДвоичныеДанные.Записать(ПутьКЛокальномуФайлу);
Сообщить("Файл успешно скачан!");
ИначеЕсли Ответ.КодСостояния = 301 Или Ответ.КодСостояния = 302 Тогда
// Обработка перенаправления
НовыйАдрес = Ответ.Заголовки.Получить("Location");
Сообщить("Файл перемещен. Новый адрес: " + НовыйАдрес);
Иначе
Сообщить("Ошибка при скачивании. Код состояния: " + Ответ.КодСостояния);
КонецЕсли;
Исключение
Сообщить("Произошла ошибка при работе с интернет: " + ОписаниеОшибки());
КонецПопытки;
В платформе 1С существует стандартная функция КопироватьФайл(). Существует распространенное заблуждение, что она не поддерживает работу с HTTPS. На самом деле в современных релизах платформы (начиная с 8.3.14 и выше) этот метод вполне успешно работает с защищенными протоколами. Однако у него есть существенный минус — вы не можете гибко управлять процессом проверки SSL-сертификатов или передавать специфические заголовки запроса.
Посмотрим на пример использования этого метода:
АдресИсточника = "https://ermak-ufa.ru/upload/iblock/dd1/dd1ce4915bd4c9d1c66a149b90f42ce0.jpeg";
ПутьПриемника = "C:\Temp\photo.jpg";
Попытка
КопироватьФайл(АдресИсточника, ПутьПриемника);
Сообщить("Файл скопирован успешно.");
Исключение
// Здесь часто возникает ошибка "Удаленный узел не прошел проверку"
Сообщить("Не удалось скопировать файл: " + ОписаниеОшибки());
КонецПопытки;
Если при использовании этого метода вы получаете пустой файл размером 0 байт или ошибку доступа, это обычно означает, что платформа не смогла подтвердить подлинность SSL-сертификата сайта.
Выясним причину одной из самых частых проблем. Ошибка "Удаленный узел не прошел проверку" означает, что 1С не смогла построить цепочку доверия для SSL-сертификата сервера. Это случается, если:
Как решить проблему?
Во-первых, проверьте настройки даты и времени на сервере, где выполняется код. Во-вторых, если вы используете HTTPСоединение, вы можете попробовать инициализировать ЗащищенноеСоединениеOpenSSL с явным указанием игнорирования проверок (хотя это крайне не рекомендуется для рабочих систем):
// Использование системных сертификатов без жесткой проверки (зависит от настроек ОС)
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Неопределено);
В-третьих, для серверных вызовов убедитесь, что сертификат удостоверяющего центра установлен в хранилище "Локальный компьютер" (а не только "Текущий пользователь").
Иногда при попытке скачать файл вы получаете пустой ответ с кодом 301 или 302. Проанализируем ситуацию: это не ошибка, а указание сервера на то, что ресурс переехал. Ссылка на новый адрес файла содержится в заголовке ответа под ключом Location.
В новых версиях платформы 8.3.20+ у объекта HTTPСоединение появилось свойство ИспользоватьАвтоматическоеПеренаправление. Если установить его в Истина, платформа сама выполнит повторный запрос по новому адресу. Для более старых версий вам придется вручную получить заголовок и создать новое соединение к новому хосту.
Проанализируем пример получения ссылки из заголовков:
Если Ответ.КодСостояния = 301 Тогда
НовыйURL = Ответ.Заголовки.Получить("Location");
// Здесь нужно распарсить НовыйURL, так как он может вести на другой домен
// и создать новое HTTPСоединение.
КонецЕсли;
Часто ссылка на картинку приходит к нам в составе JSON-структуры. Разберем комплексный пример, где мы сначала получаем список товаров, а затем скачиваем фото для каждого из них:
// 1. Получаем JSON с данными о товарах
СоединениеAPI = Новый HTTPСоединение("www.sima-land.ru",,,,,, Новый ЗащищенноеСоединениеOpenSSL());
ЗапросAPI = Новый HTTPЗапрос("/api/v3/item/?sid=3098609");
ОтветAPI = СоединениеAPI.Получить(ЗапросAPI);
Если ОтветAPI.КодСостояния = 200 Тогда
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(ОтветAPI.ПолучитьТелоКакСтроку());
Данные = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
// 2. Обходим массив товаров
Для каждого Товар из Данные["items"] Цикл
URLКартинки = Товар["photoUrl"]; // Например: https://cdn.site.com/img.jpg
// Извлекаем имя файла для сохранения
ИмяФайла = "D:\Photos\" + Товар["sid"] + ".jpg";
// 3. Используем универсальный метод скачивания
КопироватьФайл(URLКартинки, ИмяФайла);
КонецЦикла;
КонецЕсли;
Подводя итог, можно сказать: для простых задач в актуальных версиях 1С достаточно использовать КопироватьФайл(), убедившись в актуальности сертификатов системы. Для сложных задач, требующих авторизации, обработки редиректов или работы под разными операционными системами (включая Linux-серверы), следует использовать HTTPСоединение с настроенным ЗащищенноеСоединениеOpenSSL.