Как в 1С программно скачать файл (картинку) по протоколу HTTPS?

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

В современной разработке на платформе 1С:Предприятие 8.3 все чаще приходится сталкиваться с необходимостью интеграции с внешними сайтами и API. Одной из типовых задач является получение изображений товаров. Если раньше многие сайты работали по незащищенному протоколу HTTP, то сегодня повсеместным стандартом стал HTTPS. Это накладывает определенные требования к коду 1С, так как простые методы копирования файлов могут выдавать ошибки доступа или проверки сертификатов.

В этой статье мы подробно разберем, как правильно организовать скачивание картинок по защищенному соединению, рассмотрим основные ошибки и выясним, какой метод является наиболее универсальным.

Использование объекта HTTPСоединение с поддержкой SSL

Наиболее правильным и гибким способом работы с 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-сертификата сервера. Это случается, если:

  1. На сервере используется самоподписанный сертификат.
  2. Используется современный сертификат (например, Let's Encrypt), а корневые сертификаты в операционной системе устарели.
  3. Сертификат сайта просрочен.
  4. На компьютере неверно установлена дата или часовой пояс (сертификаты имеют строгий срок действия).

Как решить проблему?

Во-первых, проверьте настройки даты и времени на сервере, где выполняется код. Во-вторых, если вы используете HTTPСоединение, вы можете попробовать инициализировать ЗащищенноеСоединениеOpenSSL с явным указанием игнорирования проверок (хотя это крайне не рекомендуется для рабочих систем):


// Использование системных сертификатов без жесткой проверки (зависит от настроек ОС)
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Неопределено);

В-третьих, для серверных вызовов убедитесь, что сертификат удостоверяющего центра установлен в хранилище "Локальный компьютер" (а не только "Текущий пользователь").

Обработка кода ответа 301 (Перенаправление)

Иногда при попытке скачать файл вы получаете пустой ответ с кодом 301 или 302. Проанализируем ситуацию: это не ошибка, а указание сервера на то, что ресурс переехал. Ссылка на новый адрес файла содержится в заголовке ответа под ключом Location.

В новых версиях платформы 8.3.20+ у объекта HTTPСоединение появилось свойство ИспользоватьАвтоматическоеПеренаправление. Если установить его в Истина, платформа сама выполнит повторный запрос по новому адресу. Для более старых версий вам придется вручную получить заголовок и создать новое соединение к новому хосту.

Проанализируем пример получения ссылки из заголовков:


Если Ответ.КодСостояния = 301 Тогда
    НовыйURL = Ответ.Заголовки.Получить("Location");
    // Здесь нужно распарсить НовыйURL, так как он может вести на другой домен
    // и создать новое HTTPСоединение.
КонецЕсли;

Интеграция: парсинг ссылки из JSON и скачивание

Часто ссылка на картинку приходит к нам в составе 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.

← На главную