Загрузка изображений из интернета по прямой ссылке, особенно если требуется поддержка защищенного протокола HTTPS, является частой задачей при интеграции 1С с внешними системами или веб-сайтами. В этом материале мы подробно рассмотрим различные подходы и примеры кода для решения этой проблемы, ориентируясь на типовые механизмы платформы 1С:Предприятие.
Существует несколько способов программной загрузки файлов из интернета в 1С. Мы разберем два основных подхода: использование метода КопироватьФайл и более универсальный метод с применением объектов HTTPСоединение и HTTPЗапрос. Также уделим внимание аспектам работы с защищенными соединениями, обработке ответов сервера и сохранению файлов в информационной базе.
Функция КопироватьФайл(откуда, куда) является одним из самых простых способов копирования файлов. Она поддерживает работу с сетевыми адресами, включая схемы HTTP, HTTPS и FTP. Это означает, что вы можете указать URL-адрес файла в качестве источника.
Посмотрим на общую структуру вызова:
ИмяФайлаНаСервере = ПолучитьИмяВременногоФайла(".jpg"); // Создаем временный файл
Если КопироватьФайл("https://example.com/картинка.jpg", ИмяФайлаНаСервере) Тогда
// Файл успешно загружен во временный файл
// Далее можно прочитать его как двоичные данные или вставить в базу
ДвоичныеДанные = Новый ДвоичныеДанные(ИмяФайлаНаСервере);
// ... дальнейшая обработка ...
Иначе
// Ошибка загрузки файла
КонецЕсли;
Однако, важно учитывать некоторые ограничения при использовании этой функции:
КопироватьФайл работает только с локальными файлами. Это означает, что для загрузки файла из интернета на веб-клиенте напрямую через КопироватьФайл не получится. Файл сначала придется сохранить на локальный диск пользователя, а затем уже использовать КопироватьФайл для работы с ним.Таким образом, для универсальной загрузки из интернета, особенно в условиях клиент-серверного взаимодействия и работы в веб-клиенте, мы рекомендуем использовать более гибкий подход с HTTPСоединение и HTTPЗапрос.
Этот подход является наиболее мощным и универсальным для взаимодействия с веб-серверами. Он позволяет нам вручную устанавливать соединения, отправлять запросы, обрабатывать заголовки и получать двоичные данные файла. Мы разберем этот метод по шагам, включая работу с HTTPS и сохранение изображений в присоединенные файлы номенклатуры.
Прежде чем устанавливать HTTP-соединение, нам необходимо разобрать (спарсить) переданную ссылку на ее составные части: схему (http/https), хост, порт, путь на сервере и, при необходимости, данные авторизации (логин/пароль). Для этого мы можем использовать вспомогательную функцию СтруктураURI.
Вот пример реализации функции СтруктураURI, которая извлекает все необходимые компоненты из URL:
&НаСервере
Функция СтруктураURI(Знач СтрокаURI) Экспорт
СтрокаURI = СокрЛП(СтрокаURI);
// схема
Схема = "";
Позиция = Найти(СтрокаURI, "://");
Если Позиция > 0 Тогда
Схема = НРег(Лев(СтрокаURI, Позиция - 1));
СтрокаURI = Сред(СтрокаURI, Позиция + 3);
КонецЕсли;
// строка соединения и путь на сервере
СтрокаСоединения = СтрокаURI;
ПутьНаСервере = "";
Позиция = Найти(СтрокаСоединения, "/");
Если Позиция > 0 Тогда
ПутьНаСервере = Сред(СтрокаСоединения, Позиция + 1);
СтрокаСоединения = Лев(СтрокаСоединения, Позиция - 1);
КонецЕсли;
// информация пользователя и имя сервера
СтрокаАвторизации = "";
ИмяСервера = СтрокаСоединения;
Позиция = Найти(СтрокаСоединения, "@");
Если Позиция > 0 Тогда
СтрокаАвторизации = Лев(СтрокаСоединения, Позиция - 1);
ИмяСервера = Сред(СтрокаСоединения, Позиция + 1);
КонецЕсли;
// логин и пароль
Логин = СтрокаАвторизации;
Пароль = "";
Позиция = Найти(СтрокаАвторизации, ":");
Если Позиция > 0 Тогда
Логин = Лев(СтрокаАвторизации, Позиция - 1);
Пароль = Сред(СтрокаАвторизации, Позиция + 1);
КонецЕсли;
// хост и порт
Хост = ИмяСервера;
Порт = "";
Позиция = Найти(ИмяСервера, ":");
Если Позиция > 0 Тогда
Хост = Лев(ИмяСервера, Позиция - 1);
Порт = Сред(ИмяСервера, Позиция + 1);
КонецЕсли;
Результат = Новый Структура;
Результат.Вставить("Схема", Схема);
Результат.Вставить("Логин", Логин);
Результат.Вставить("Пароль", Пароль);
Результат.Вставить("ИмяСервера", ИмяСервера);
Результат.Вставить("Хост", Хост);
Результат.Вставить("Порт", ?(Порт <> "", Число(Порт), Неопределено));
Результат.Вставить("ПутьНаСервере", ПутьНаСервере);
Возврат Результат;
КонецФункции
Эта функция возвращает структуру, которая содержит все необходимые данные для создания HTTP-соединения и запроса. Например, если входная строка "https://user:pass@host.com:8080/path/to/resource.jpg", функция вернет структуру с полями: "Схема" = "https", "Хост" = "host.com", "Порт" = 8080, "ПутьНаСервере" = "path/to/resource.jpg", "Логин" = "user", "Пароль" = "pass".
Для создания соединения используем объект HTTPСоединение. Если ссылка использует протокол HTTPS, нам потребуется объект ЗащищенноеСоединениеOpenSSL для обеспечения безопасного соединения.
СтруктураURI = СтруктураURI(УРЛОсновнойКартинки_); // Используем нашу вспомогательную функцию
Защита = Неопределено;
Если СокрЛП(СтруктураURI.Схема) = "https" Тогда
Защита = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Неопределено);
// Дополнительно ЗащищенноеСоединениеOpenSSL может принимать параметры для
// клиентских сертификатов и сертификатов удостоверяющих центров для более строгой аутентификации.
// Например: Новый ЗащищенноеСоединениеOpenSSL(СертификатКлиента, СертификатыУЦ)
КонецЕсли;
HTTPСоединение = Новый HTTPСоединение(СтруктураURI.Хост,
?(СтруктураURI.Порт <> Неопределено, СтруктураURI.Порт, Неопределено),
СтруктураURI.Логин,
СтруктураURI.Пароль,
,,
Защита);
Обратите внимание, что объект ЗащищенноеСоединениеOpenSSL в веб-клиенте не обеспечивает безопасность соединения, и соединение КриптоПро там не поддерживается. Также мы передаем логин и пароль в конструктор HTTPСоединение, если они были указаны в URI.
После установления соединения мы создаем объект HTTPЗапрос, указывая путь к ресурсу на сервере. Затем отправляем запрос методом Получить объекта HTTPСоединение. Важно обработать возможные ошибки и коды состояния HTTP-ответа, чтобы убедиться в успешной загрузке файла.
Рассмотрим пример кода для проверки доступности картинки, который возвращает "Удача" или "Ошибка" в зависимости от HTTP-кода состояния:
HTTPЗапрос = Новый HTTPЗапрос(СтруктураURI.ПутьНаСервере);
// Для более сложных запросов и интеграций с внешними системами
// может потребоваться установка дополнительных заголовков, например:
// HTTPЗапрос.УстановитьЗаголовок("User-Agent", "1CEnterprise/8.3");
// HTTPЗапрос.УстановитьЗаголовок("Accept", "image/jpeg, image/png, image/*");
Попытка
Результат = HTTPСоединение.Получить(HTTPЗапрос);
Исключение
Возврат "Ошибка";
КонецПопытки;
// Анализируем код состояния HTTP-ответа
Если Результат.КодСостояния >= 400 И Результат.КодСостояния < 500 Тогда
// Ошибки клиента (например, 404 Not Found, 403 Forbidden)
Возврат "Ошибка";
ИначеЕсли Результат.КодСостояния >= 500 И Результат.КодСостояния < 600 Тогда
// Ошибки сервера (например, 500 Internal Server Error)
Возврат "Ошибка";
ИначеЕсли Результат.КодСостояния >= 300 И Результат.КодСостояния < 400 Тогда
// Перенаправления (например, 301 Moved Permanently).
// В данном случае мы просто считаем это ошибкой, но можно реализовать логику следования за перенаправлением.
Возврат "Ошибка";
ИначеЕсли Результат.КодСостояния < 300 Тогда
// Успешный ответ (2xx коды, например, 200 OK)
Возврат "Удача";
КонецЕсли;
В этом коде мы проверяем различные диапазоны HTTP-кодов состояния:
Location. В нашем примере мы считаем это ошибкой для простоты.Если запрос был успешным (код состояния менее 300), мы можем получить тело ответа как двоичные данные и сохранить их. Мы рассмотрим сохранение изображения в присоединенные файлы номенклатуры, что является стандартным подходом в типовых конфигурациях 1С.
// ... код установления соединения и отправки запроса, как в Шаге 2 и 3 ...
// Предполагаем, что Результат.КодСостояния < 300
Если Результат.КодСостояния < 300 Тогда
ДвоичныеДанныеКартинки = Результат.ПолучитьТелоКакДвоичныеДанные();
// Создаем уникальное имя для файла во временном хранилище
НовоеИмяФайла = Новый УникальныйИдентификатор();
// Помещаем двоичные данные во временное хранилище
// Это важно для передачи больших объемов данных между клиентом и сервером.
АдресВременногоХранилищаФайла = ПоместитьВоВременноеХранилище(ДвоичныеДанныеКартинки);
// Добавляем файл к объекту Номенклатура как присоединенный файл
// Предполагается, что у вас есть ссылка на объект Номенклатура
ПрисоединенныйФайл = ПрисоединенныеФайлы.ДобавитьФайл(Номенклатура, НовоеИмяФайла, СтрЗаменить("картинка.jpg",".",""), ТекущаяДата(), ТекущаяДата(), АдресВременногоХранилищаФайла, "Изображение загружено обработкой");
Если ЗначениеЗаполнено(ПрисоединенныйФайл) Тогда
// Если это основная картинка, то привязываем ее к реквизиту ФайлКартинки номенклатуры
Если ЭтоОсновнаяКартинка = Истина Тогда // Предполагается, что есть переменная ЭтоОсновнаяКартинка
НоменклатураОбъект = Номенклатура.ПолучитьОбъект();
НоменклатураОбъект.ФайлКартинки = ПрисоединенныйФайл;
НоменклатураОбъект.Записать();
КонецЕсли;
КонецЕсли;
КонецЕсли;
Рассмотрим ключевые моменты в этом коде:
ДвоичныеДанныеКартинки = Результат.ПолучитьТелоКакДвоичныеДанные();: Этот метод объекта HTTPОтвет извлекает содержимое ответа сервера в виде двоичных данных, которые идеально подходят для изображений.НовоеИмяФайла = Новый УникальныйИдентификатор();: Мы генерируем уникальный идентификатор для нового файла, чтобы избежать коллизий имен при сохранении.АдресВременногоХранилищаФайла = ПоместитьВоВременноеХранилище(ДвоичныеДанныеКартинки);: Этот метод помещает двоичные данные во временное хранилище на сервере 1С. Это стандартный механизм для передачи больших объемов данных между клиентской и серверной частями приложения, а также для временного хранения файлов перед их окончательным размещением.ПрисоединенныеФайлы.ДобавитьФайл(...): Этот метод является частью стандартной подсистемы "Присоединенные файлы", которая присутствует во многих типовых конфигурациях. Он позволяет прикрепить файл к определенному объекту (в нашем случае, к Номенклатура), сохраняя его в информационной базе или на внешних томах хранения. В качестве параметров указываются владелец файла, уникальный идентификатор, имя, даты создания/изменения, адрес во временном хранилище и описание.ФайлКартинки и записываем объект.При хранении изображений в 1С мы имеем несколько вариантов, каждый из которых имеет свои преимущества и недостатки:
ХранилищеЗначения):
В большинстве случаев для прикрепленных файлов типовые конфигурации используют собственную подсистему, которая позволяет администратору выбрать место хранения (в базе или на томах).
Для более интерактивной работы с файлами, особенно в веб-клиенте, могут быть полезны следующие методы глобального контекста:
НачатьПомещениеФайлаНаСервер(): Позволяет инициировать процесс загрузки файла с клиента на сервер. Он может работать в интерактивном режиме (с диалогом выбора файлов) и, в отличие от КопироватьФайл, в веб-клиенте не требует установки расширения работы с файлами для загрузки файлов, выбранных пользователем.НачатьПолучениеФайлаССервера(): Позволяет скачать файл с сервера на клиент.НачатьЗапросРазрешенияПользователя(): В веб-клиенте может потребоваться запрос разрешения на доступ к диску. Этот метод позволяет запросить разрешение на группу операций, чтобы избежать множественных запросов к пользователю.Эти методы полезны, когда пользователь сам выбирает файл для загрузки или сохранения, в то время как наш основной метод с HTTPСоединение предназначен для программной загрузки по URL.
Если ваша задача — массовая загрузка изображений для товаров, и вы не хотите погружаться в программирование, то существуют готовые обработки и модули, которые автоматизируют этот процесс. Такие обработки, как, например, упомянутая "Загрузка изображений для товара", обычно предлагают расширенный функционал:
Использование готовых решений может значительно ускорить процесс и снизить трудозатраты на разработку и отладку, особенно для не-программистов.
Мы рассмотрели различные методы программной загрузки изображений из интернета в 1С. Для простых случаев и локального использования можно применять КопироватьФайл. Однако для универсальных и надежных решений, особенно при работе с HTTPS и в условиях клиент-серверного взаимодействия, наиболее подходящим является использование связки HTTPСоединение и HTTPЗапрос. Этот подход обеспечивает полный контроль над процессом запроса и обработки ответа, позволяя гибко управлять загрузкой и сохранением данных в вашей информационной базе 1С.
Не забывайте о важности правильной обработки ошибок HTTP, управлении защищенными соединениями и эффективных способах хранения файлов в 1С, таких как присоединенные файлы и тома хранения.