Разработка и Конфигурация · 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Ответ. Ключевой метод ответа для картинок — ПолучитьТелоКакДвоичныеДанные(): он возвращает содержимое «как есть», без попыток интерпретировать текст. Конструктор Новый Картинка(ДвоичныеДанные) создаёт объект картинки, который уже можно вывести в форму или сохранить.
Если ссылка приходит целиком, её нужно разобрать. Простой вариант — найти первый слеш после имени сервера: всё до него — адрес сервера, всё после — путь к ресурсу. Учтите, что в пути могут быть параметры запроса после знака вопроса — их нужно оставить в адресе ресурса, а не отбрасывать.
Соединение = Новый HTTPСоединение("example.com");
Запрос = Новый HTTPЗапрос("/images/photo.jpg");
Ответ = Соединение.Получить(Запрос);
ДвоичныеДанные = Ответ.ПолучитьТелоКакДвоичныеДанные();
Картинка = Новый Картинка(ДвоичныеДанные);Загрузка по HTTPS: защищённое соединение
Большинство ссылок сейчас ведут на HTTPS-ресурсы. Если передать такой адрес в обычное HTTPСоединение, запрос либо уйдёт на порт 80 и вернёт перенаправление, либо завершится ошибкой соединения. Для защищённого протокола в конструктор HTTPСоединение нужно передать объект защищённого соединения.
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение(АдресСервера, , , , , , ЗащищенноеСоединение);
Конструктор ЗащищенноеСоединениеOpenSSL можно вызывать без параметров — тогда используется проверка сертификата по умолчанию. Если сервер работает с самоподписанным сертификатом (типично для тестовых стендов), проверку можно отключить, передав Новый СертификатыУдостоверяющихЦентровОС не применяется — вместо этого используется конструктор с параметрами, где клиентский сертификат и проверка задаются явно. В продуктиве отключать проверку сертификата не стоит: это открывает возможность подмены сервера.
Определить, нужно ли защищённое соединение, просто: если ссылка начинается с https:// — создавайте соединение с OpenSSL, если с http:// — обычное. Удобно оформить это в одну функцию-фабрику, которая принимает полный URL и возвращает готовое соединение.
Как вывести картинку в управляемой форме
В управляемых формах картинку нельзя присвоить реквизиту напрямую как объект Картинка — поле с видом «Поле картинки» работает либо с адресом во временном хранилище, либо со ссылкой на данные. Стандартный приём: поместить двоичные данные во временное хранилище и присвоить адрес реквизиту формы типа «Строка».
ДвоичныеДанные = Ответ.ПолучитьТелоКакДвоичныеДанные();
АдресКартинки = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);
Здесь АдресКартинки — строковый реквизит формы, привязанный к элементу «Поле картинки». Второй параметр ПоместитьВоВременноеХранилище привязывает данные к жизненному циклу формы, иначе хранилище очистится после завершения серверного вызова, и картинка пропадёт.
Если загрузка выполняется на клиенте (тонкий или веб-клиент), HTTPСоединение также доступен, но помните про ограничения веб-клиента и кросс-доменные ограничения браузера. Надёжнее выполнять загрузку на сервере в вызове &НаСервере, а на клиент передавать только адрес хранилища.
- 1Разберите URL на адрес сервера и путь к файлу
- 2Создайте HTTPСоединение: с ЗащищенноеСоединениеOpenSSL для https, без него для http
- 3Выполните GET-запрос методом Получить() и проверьте код состояния 200
- 4Получите тело ответа методом ПолучитьТелоКакДвоичныеДанные()
- 5Поместите двоичные данные во временное хранилище или создайте объект Картинка
- 6Привяжите адрес хранилища к реквизиту формы или сохраните данные в базу
Сохранение картинки в базу данных
Для постоянного хранения изображения в типовых конфигурациях используют реквизиты типа «ХранилищеЗначения» или присоединённые файлы (в конфигурациях на БСП — механизм «Работа с файлами»). В простейшем случае двоичные данные упаковываются в хранилище и записываются в реквизит элемента справочника.
ЭлементОбъект = Справочники.Номенклатура.НайтиПоКоду(КодТовара).ПолучитьОбъект();
ЭлементОбъект.ДанныеКартинки = Новый ХранилищеЗначения(ДвоичныеДанные, Новый СжатиеДанных(9));
ЭлементОбъект.Записать();
Сжатие данных при помещении в хранилище уменьшает размер базы, что заметно при тысячах изображений. При чтении данные извлекаются вызовом Элемент.ДанныеКартинки.Получить() — возвращаются те же двоичные данные, которые снова можно превратить в картинку или поместить во временное хранилище.
Если конфигурация построена на Библиотеке стандартных подсистем, предпочтительнее использовать присоединённые файлы: они хранятся в отдельном справочнике, поддерживают версии и не раздувают основную таблицу номенклатуры. Для добавления файла программно используется метод РаботаСФайлами.ДобавитьФайл() (в новых версиях — РаботаСФайлами.ДобавитьПрисоединенныйФайл).
Обработка ошибок и проверка результата
Код состояния 200 — необходимое, но не достаточное условие: сервер может вернуть HTML-страницу с ошибкой вместо изображения. Поэтому полезно дополнительно проверять заголовок Content-Type ответа — для картинок он начинается с image/, и размер полученных данных.
Конструктор Новый Картинка(ДвоичныеДанные) сам выступает проверкой: если данные не являются поддерживаемым изображением, будет вызвано исключение. Оберните создание картинки в попытку и при ошибке логируйте адрес ссылки — это сильно упрощает поиск «битых» URL при массовой загрузке.
Также учитывайте перенаправления: коды 301/302 означают, что ресурс переехал, и в заголовке Location лежит новый адрес. HTTPСоединение не следует редиректам автоматически — обработку нужно реализовать самостоятельно, повторив запрос по новому адресу.
Как проверить результат
200 — тело содержит данные файла
404, 403, 500 — файл недоступен, 301/302 — нужен повторный запрос по Location
image/jpeg, image/png и подобные
text/html — сервер вернул страницу вместо картинки
Новый Картинка(ДвоичныеДанные) выполняется без исключения
Исключение — данные повреждены или это не изображение
Картинка видна после присвоения адреса хранилища
Пустое поле — хранилище очищено или адрес не привязан к форме
Типичные ошибки и ограничения
Самая частая причина пустого результата — отсутствие защищённого соединения для HTTPS-ссылки. Вторая по частоте — попытка прочитать тело ответа как строку: метод ПолучитьТелоКакСтроку() испортит бинарные данные, и картинка не откроется. Для файлов всегда используйте ПолучитьТелоКакДвоичныеДанные() или ПолучитьТелоКакПоток().
При массовой загрузке изображений учитывайте таймауты: по умолчанию соединение ждёт ответа ограниченное время, и при недоступном сервере обработка «зависнет» на каждой ссылке. Задавайте таймаут явно (параметр конструктора 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 и обработка редиректов.