К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как в 1С получить картинку по ссылке

Как в 1С получить картинку по ссылке через HTTPСоединение и HTTPЗапрос: пошаговый код, сохранение во временное хранилище, обработка ошибок и типичные проблемы.

Задача загрузить картинку по ссылке в 1С возникает при обмене с сайтами, маркетплейсами и веб-сервисами: платформа передаёт URL изображения товара, а его нужно показать в карточке номенклатуры или сохранить в базу. Встроенного языка 1С достаточно для решения — используются объекты HTTPСоединение и HTTPЗапрос, доступные и на толстом, и на тонком клиенте.

Общая схема проста: разобрать URL на сервер и путь, открыть HTTP- или HTTPS-соединение, выполнить GET-запрос, получить ответ как двоичные данные и преобразовать их в объект Картинка или сохранить в файл. Дальше двоичные данные можно поместить во временное хранилище и привязать к реквизиту формы или записать в хранилище значений справочника.

Ниже разобран рабочий код для управляемых и обычных форм, нюансы защищённых соединений, проверка результата и типичные ошибки, из-за которых картинка не загружается или загружается «битой».

Базовый код: HTTPСоединение и HTTPЗапрос

Минимальный пример получения картинки по адресу вида https://example.com/images/photo.jpg. Ссылку удобно разбивать на сервер и ресурс вручную или через структуру.

Функция ПолучитьКартинкуПоСсылке(АдресСервера, ПутьКФайлу) Экспорт

Соединение = Новый HTTPСоединение(АдресСервера);

Запрос = Новый HTTPЗапрос(ПутьКФайлу);

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

Если Ответ.КодСостояния = 200 Тогда

ДвоичныеДанные = Ответ.ПолучитьТелоКакДвоичныеДанные();

Возврат Новый Картинка(ДвоичныеДанные);

Иначе

ВызватьИсключение "Ошибка загрузки: код " + Ответ.КодСостояния;

КонецЕсли;

КонецФункции

Метод Получить() объекта HTTPСоединение выполняет GET-запрос и возвращает HTTPОтвет. Ключевой метод ответа для картинок — ПолучитьТелоКакДвоичныеДанные(): он возвращает содержимое «как есть», без попыток интерпретировать текст. Конструктор Новый Картинка(ДвоичныеДанные) создаёт объект картинки, который уже можно вывести в форму или сохранить.

Если ссылка приходит целиком, её нужно разобрать. Простой вариант — найти первый слеш после имени сервера: всё до него — адрес сервера, всё после — путь к ресурсу. Учтите, что в пути могут быть параметры запроса после знака вопроса — их нужно оставить в адресе ресурса, а не отбрасывать.

bsl
Соединение = Новый HTTPСоединение("example.com");
Запрос = Новый HTTPЗапрос("/images/photo.jpg");
Ответ = Соединение.Получить(Запрос);
ДвоичныеДанные = Ответ.ПолучитьТелоКакДвоичныеДанные();
Картинка = Новый Картинка(ДвоичныеДанные);

Загрузка по HTTPS: защищённое соединение

Большинство ссылок сейчас ведут на HTTPS-ресурсы. Если передать такой адрес в обычное HTTPСоединение, запрос либо уйдёт на порт 80 и вернёт перенаправление, либо завершится ошибкой соединения. Для защищённого протокола в конструктор HTTPСоединение нужно передать объект защищённого соединения.

ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();

Соединение = Новый HTTPСоединение(АдресСервера, , , , , , ЗащищенноеСоединение);

Конструктор ЗащищенноеСоединениеOpenSSL можно вызывать без параметров — тогда используется проверка сертификата по умолчанию. Если сервер работает с самоподписанным сертификатом (типично для тестовых стендов), проверку можно отключить, передав Новый СертификатыУдостоверяющихЦентровОС не применяется — вместо этого используется конструктор с параметрами, где клиентский сертификат и проверка задаются явно. В продуктиве отключать проверку сертификата не стоит: это открывает возможность подмены сервера.

Определить, нужно ли защищённое соединение, просто: если ссылка начинается с https:// — создавайте соединение с OpenSSL, если с http:// — обычное. Удобно оформить это в одну функцию-фабрику, которая принимает полный URL и возвращает готовое соединение.

Как вывести картинку в управляемой форме

В управляемых формах картинку нельзя присвоить реквизиту напрямую как объект Картинка — поле с видом «Поле картинки» работает либо с адресом во временном хранилище, либо со ссылкой на данные. Стандартный приём: поместить двоичные данные во временное хранилище и присвоить адрес реквизиту формы типа «Строка».

ДвоичныеДанные = Ответ.ПолучитьТелоКакДвоичныеДанные();

АдресКартинки = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);

Здесь АдресКартинки — строковый реквизит формы, привязанный к элементу «Поле картинки». Второй параметр ПоместитьВоВременноеХранилище привязывает данные к жизненному циклу формы, иначе хранилище очистится после завершения серверного вызова, и картинка пропадёт.

Если загрузка выполняется на клиенте (тонкий или веб-клиент), HTTPСоединение также доступен, но помните про ограничения веб-клиента и кросс-доменные ограничения браузера. Надёжнее выполнять загрузку на сервере в вызове &НаСервере, а на клиент передавать только адрес хранилища.

Порядок действий
  1. 1
    Разберите URL на адрес сервера и путь к файлу
  2. 2
    Создайте HTTPСоединение: с ЗащищенноеСоединениеOpenSSL для https, без него для http
  3. 3
    Выполните GET-запрос методом Получить() и проверьте код состояния 200
  4. 4
    Получите тело ответа методом ПолучитьТелоКакДвоичныеДанные()
  5. 5
    Поместите двоичные данные во временное хранилище или создайте объект Картинка
  6. 6
    Привяжите адрес хранилища к реквизиту формы или сохраните данные в базу

Сохранение картинки в базу данных

Для постоянного хранения изображения в типовых конфигурациях используют реквизиты типа «ХранилищеЗначения» или присоединённые файлы (в конфигурациях на БСП — механизм «Работа с файлами»). В простейшем случае двоичные данные упаковываются в хранилище и записываются в реквизит элемента справочника.

ЭлементОбъект = Справочники.Номенклатура.НайтиПоКоду(КодТовара).ПолучитьОбъект();

ЭлементОбъект.ДанныеКартинки = Новый ХранилищеЗначения(ДвоичныеДанные, Новый СжатиеДанных(9));

ЭлементОбъект.Записать();

Сжатие данных при помещении в хранилище уменьшает размер базы, что заметно при тысячах изображений. При чтении данные извлекаются вызовом Элемент.ДанныеКартинки.Получить() — возвращаются те же двоичные данные, которые снова можно превратить в картинку или поместить во временное хранилище.

Если конфигурация построена на Библиотеке стандартных подсистем, предпочтительнее использовать присоединённые файлы: они хранятся в отдельном справочнике, поддерживают версии и не раздувают основную таблицу номенклатуры. Для добавления файла программно используется метод РаботаСФайлами.ДобавитьФайл() (в новых версиях — РаботаСФайлами.ДобавитьПрисоединенныйФайл).

Обработка ошибок и проверка результата

Код состояния 200 — необходимое, но не достаточное условие: сервер может вернуть HTML-страницу с ошибкой вместо изображения. Поэтому полезно дополнительно проверять заголовок Content-Type ответа — для картинок он начинается с image/, и размер полученных данных.

Конструктор Новый Картинка(ДвоичныеДанные) сам выступает проверкой: если данные не являются поддерживаемым изображением, будет вызвано исключение. Оберните создание картинки в попытку и при ошибке логируйте адрес ссылки — это сильно упрощает поиск «битых» URL при массовой загрузке.

Также учитывайте перенаправления: коды 301/302 означают, что ресурс переехал, и в заголовке Location лежит новый адрес. HTTPСоединение не следует редиректам автоматически — обработку нужно реализовать самостоятельно, повторив запрос по новому адресу.

Контрольные точки

Как проверить результат

Код состояния ответа
Норма

200 — тело содержит данные файла

Тревожный признак

404, 403, 500 — файл недоступен, 301/302 — нужен повторный запрос по Location

Заголовок Content-Type
Норма

image/jpeg, image/png и подобные

Тревожный признак

text/html — сервер вернул страницу вместо картинки

Создание объекта Картинка
Норма

Новый Картинка(ДвоичныеДанные) выполняется без исключения

Тревожный признак

Исключение — данные повреждены или это не изображение

Отображение в форме
Норма

Картинка видна после присвоения адреса хранилища

Тревожный признак

Пустое поле — хранилище очищено или адрес не привязан к форме

Типичные ошибки и ограничения

Самая частая причина пустого результата — отсутствие защищённого соединения для HTTPS-ссылки. Вторая по частоте — попытка прочитать тело ответа как строку: метод ПолучитьТелоКакСтроку() испортит бинарные данные, и картинка не откроется. Для файлов всегда используйте ПолучитьТелоКакДвоичныеДанные() или ПолучитьТелоКакПоток().

При массовой загрузке изображений учитывайте таймауты: по умолчанию соединение ждёт ответа ограниченное время, и при недоступном сервере обработка «зависнет» на каждой ссылке. Задавайте таймаут явно (параметр конструктора HTTPСоединение) и обрабатывайте исключения, чтобы одна недоступная ссылка не прерывала весь обмен.

Ещё одно ограничение — права пользователя и контекст выполнения. В фоновых заданиях временное хранилище, привязанное к форме, недоступно: возвращайте из фонового задания адрес хранилища с явным идентификатором или сохраняйте данные сразу в базу. Также помните, что объёмные картинки раздувают базу и журналы обмена — при больших каталогах имеет смысл хранить файлы в томах или на диске.

Типичные ошибки
01
Чтение тела через ПолучитьТелоКакСтроку() — бинарные данные портятся, картинка не открывается
02
Игнорирование кодов 301/302 — запрос уходит на старый адрес и возвращает пустой ответ
03
Помещение во временное хранилище без идентификатора формы — картинка исчезает после серверного вызова
04
Отсутствие таймаута — обработка зависает на недоступном сервере
05
Загрузка без проверки Content-Type — в базу записывается HTML-страница ошибки

Альтернативные способы получения файла

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

В конфигурациях на БСП есть программный интерфейс ПолучениеФайловИзИнтернета с методами скачивания, которые уже учитывают прокси-сервер и возвращают структуру с признаком успеха и текстом ошибки. Если библиотека внедрена, используйте её вместо самописного кода — меньше кода для сопровождения и корректная работа через прокси из коробки.

Сравнение вариантов

HTTPСоединение + HTTPЗапрос

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

ПолучениеФайловИзИнтернета (БСП)

Готовый серверный API с поддержкой прокси и структурой результата. Требует внедрённой Библиотеки стандартных подсистем

ПолучитьФайлИзИнтернета()

Простейший вызов, сохраняет файл сразу на диск. Минимум гибкости: нет тонкой обработки заголовков и состояний

FAQ

Почему запрос по HTTPS-ссылке возвращает ошибку соединения?

Потому что HTTPСоединение по умолчанию работает по обычному HTTP. Для адресов https:// передайте в конструктор соединения объект Новый ЗащищенноеСоединениеOpenSSL() — тогда будет использоваться TLS-канал и порт 443.

Как показать загруженную картинку в управляемой форме?

Поместите двоичные данные во временное хранилище с передачей УникальныйИдентификатор формы и присвойте полученный адрес строковому реквизиту, связанному с элементом «Поле картинки». Напрямую объект Картинка реквизиту формы присвоить нельзя.

Сервер вернул код 200, но картинка не открывается. Что проверить?

Проверьте заголовок Content-Type ответа: если там text/html, сервер вернул страницу вместо файла (например, заглушку авторизации). Также проверьте размер данных и попытку создать объект Картинка — исключение укажет на повреждённые данные.

Нужно ли обрабатывать редиректы 301 и 302?

Да. HTTPСоединение не следует перенаправлениям автоматически: при кодах 301/302 нужно прочитать заголовок Location и выполнить новый запрос по указанному адресу. Иначе вместо картинки вы получите пустой ответ.

Можно ли загружать картинки в фоновом задании?

Можно, но временное хранилище, привязанное к форме, из фонового задания недоступно. Возвращайте из задания адрес хранилища, созданного с явным идентификатором, или сразу сохраняйте двоичные данные в базу, а форму обновляйте после завершения задания.

Итог

Что важно запомнить

Картинка по ссылке получается через HTTPСоединение и GET-запрос с чтением тела как двоичных данных. Для HTTPS обязательно защищённое соединение OpenSSL, для показа в форме — временное хранилище, для надёжности — проверка кода состояния, Content-Type и обработка редиректов.