Как программно загрузить изображение из интернета и установить его основным для товара

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

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

Постановка задачи и анализ первичного кода

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

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

Шаг 1. Настройка защищенного соединения (SSL)

Большинство современных сайтов работают по протоколу HTTPS. Если при создании объекта HTTPСоединение не указать параметры защиты, попытка соединения завершится ошибкой или возвратом пустого тела ответа. Разберем, как правильно инициализировать соединение.

Для работы с HTTPS нам потребуется объект ЗащищенноеСоединениеOpenSSL. Посмотрим на правильный пример инициализации:


// Определяем адрес сервера (только доменное имя)
Сервер = "static.techspot.com"; 

// Создаем защищенное соединение, используя стандартные сертификаты Windows
Защита = Новый ЗащищенноеСоединениеOpenSSL(
    Новый СертификатКлиентаWindows(), 
    Новый СертификатыУдостоверяющихЦентровWindows()
);

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

Важный момент: использование Новый ЗащищенноеСоединениеOpenSSL() без параметров также допустимо в большинстве случаев, если на сервере установлены валидные и общеизвестные сертификаты.

Шаг 2. Корректное разделение URL на сервер и путь

Одной из самых частых ошибок является неправильная передача адреса в объект HTTPЗапрос. Объект HTTPСоединение принимает только имя сервера (хост), а путь к конкретному файлу должен передаваться в HTTPЗапрос.

Если полная ссылка выглядит так: https://example.com/images/product1.jpg, то:

Проанализируем ситуацию, когда сервер возвращает ошибку 404 (страница не найдена). Это происходит, если путь указан не полностью или содержит лишние префиксы протокола. Посмотрим, как это реализовать программно:


// Полный путь к файлу относительно корня сайта
ПутьКФайлу = "/images/products/2018/loudspeakers/org/product-9.jpg";

// Создаем запрос
Запрос = Новый HTTPЗапрос(ПутьКФайлу);

// Обязательно добавляем User-Agent, так как многие серверы блокируют пустые запросы
Запрос.Заголовки.Вставить("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)");

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

Шаг 3. Проверка полученных данных

Прежде чем сохранять данные в информационную базу, крайне важно убедиться, что мы получили именно изображение, а не HTML-страницу с ошибкой "404 Not Found". Если размер полученного файла составляет всего несколько килобайт, скорее всего, это текстовая страница ошибки.

Проверим код состояния ответа и тип содержимого:


Если Ответ.КодСостояния = 200 Тогда
    // Проверяем Content-Type (должен быть image/jpeg, image/png и т.д.)
    ТипСодержимого = Ответ.Заголовки.Получить("Content-Type");
    Если СтрНайти(ТипСодержимого, "image") > 0 Тогда
        ДвоичныеДанныеИзображения = Ответ.ПолучитьТелоКакДвоичныеДанные();
    Иначе
        Сообщить("Полученные данные не являются изображением!");
        Возврат;
    КонецЕсли;
Иначе
    Сообщить("Ошибка при скачивании файла. Код состояния: " + Ответ.КодСостояния);
    Возврат;
КонецЕсли;

Шаг 4. Добавление файла в справочник и установка картинки

После того как мы успешно получили ДвоичныеДанные, необходимо поместить их в систему. В конфигурациях на базе БСП (УТ 11, ERP, КА 2, БП 3) для этого используется справочник присоединенных файлов. Проанализируем процесс создания записи и связи с номенклатурой.

Сначала поместим данные во временное хранилище, а затем используем программный интерфейс БСП:


// Помещаем во временное хранилище
АдресХранилища = ПоместитьВоВременноеХранилище(ДвоичныеДанныеИзображения, Новый УникальныйИдентификатор);

// Подготавливаем параметры для добавления файла
ПараметрыФайла = Новый Структура;
ПараметрыФайла.Вставить("ВладелецФайлов", СсылкаНаНоменклатуру);
ПараметрыФайла.Вставить("ИмяБезРасширения", СсылкаНаНоменклатуру.Наименование);
ПараметрыФайла.Вставить("РасширениеБезТочки", "jpg");
ПараметрыФайла.Вставить("Автор", Пользователи.ТекущийПользователь());

// Добавляем файл через типовой механизм БСП
// Функция РаботаСФайлами.ДобавитьФайл создает элемент справочника НоменклатураПрисоединенныеФайлы
ПрисоединенныйФайлСсылка = РаботаСФайлами.ДобавитьФайл(ПараметрыФайла, АдресХранилища);

// Теперь устанавливаем этот файл как основной для карточки
Если ЗначениеЗаполнено(ПрисоединенныйФайлСсылка) Тогда
    ОбъектНоменклатура = СсылкаНаНоменклатуру.ПолучитьОбъект();
    ОбъектНоменклатура.ФайлКартинки = ПрисоединенныйФайлСсылка;
    ОбъектНоменклатура.Записать();
    Сообщить("Изображение успешно установлено!");
КонецЕсли;

Типичные проблемы и способы их решения

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

  1. Получение HTML вместо бинарных данных. Если сервер требует авторизации или сессионных кук (Cookies), он может перенаправить запрос на страницу логина. В этом случае в ДвоичныеДанные попадет HTML-код этой страницы. Всегда проверяйте содержимое через Ответ.Заголовки.
  2. Редиректы (Коды 301, 302). Стандартный метод Получить() не переходит по редиректам автоматически. Если сайт сменил структуру, вам придет пустой ответ с заголовком Location. В таком случае нужно выполнить повторный запрос по новому адресу.
  3. Блокировка по User-Agent. Многие современные ресурсы (например, облачные хранилища или хостинги картинок) блокируют запросы от библиотек, если не указан заголовок браузера. Обязательно добавляйте заголовок User-Agent, как показано в примере выше.
  4. Неправильный порт. Для HTTP используется порт 80, для HTTPS — 443. Если при работе с HTTPS не указать порт 443 или не передать объект защищенного соединения, система выдаст ошибку сетевого доступа.

Выясним причину ошибки "Файл поврежден", которая часто возникает при открытии загруженной картинки в 1С. Почти всегда это означает, что запись в справочник произошла, но данные внутри файла — это текст ошибки сервера. Для отладки можно воспользоваться методом ДвоичныеДанные.Записать("C:\temp\debug.jpg") и попробовать открыть этот файл обычным текстовым редактором (Блокнотом). Если вы увидите там теги <html>, значит, путь к картинке был указан неверно или сервер отклонил запрос.

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

← На главную