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

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

1С: как скачать файл по HTTP

Как скачать файл по HTTP в 1С: HTTPСоединение, HTTPЗапрос, примеры кода, работа с прокси, SSL и ошибками. Практическая инструкция для разработчиков.

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

Механизм одинаково работает в тонком, толстом и веб-клиенте, а также на сервере 1С:Предприятия. Код практически не отличается для платформ 8.3 и более ранних версий 8.2, но есть нюансы с безопасными соединениями (HTTPS), прокси и асинхронными вызовами в новых релизах.

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

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

Для работы по протоколу HTTP в 1С используются три связанных объекта. HTTPСоединение описывает сервер: адрес, порт, логин, пароль, прокси и защищённое соединение. HTTPЗапрос описывает сам запрос: адрес ресурса на сервере и заголовки. Метод Получить() соединения выполняет GET-запрос и возвращает объект HTTPОтвет с кодом состояния и телом.

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

Минимальный пример кода

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

Сервер = "example.com";

АдресРесурса = "/files/price.zip";

ИмяФайла = ПолучитьИмяВременногоФайла("zip");

Соединение = Новый HTTPСоединение(Сервер, 80);

Запрос = Новый HTTPЗапрос(АдресРесурса);

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

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

Сообщить("Файл сохранён: " + ИмяФайла);

Иначе

Сообщить("Ошибка загрузки, код: " + Ответ.КодСостояния);

КонецЕсли;

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

Порядок действий
  1. 1
    Разбейте URL на сервер и путь ресурса
  2. 2
    Создайте HTTPСоединение с нужным портом (80 для HTTP, 443 для HTTPS)
  3. 3
    Сформируйте HTTPЗапрос с адресом ресурса и заголовками
  4. 4
    Вызовите Получить() с именем выходного файла
  5. 5
    Проверьте КодСостояния ответа (ожидается 200)
  6. 6
    Проверьте, что файл существует и его размер больше нуля

Загрузка по HTTPS

Большинство современных сервисов работает только по защищённому протоколу. Для HTTPS в конструктор HTTPСоединение шестым параметром передаётся объект ЗащищенноеСоединениеOpenSSL, а порт указывается 443.

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

Неопределено, Новый СертификатыУдостоверяющихЦентровОС);

Соединение = Новый HTTPСоединение("example.com", 443, , , , ,

ЗащищенноеСоединение);

Использование сертификатов удостоверяющих центров операционной системы избавляет от необходимости вручную устанавливать сертификаты на каждое рабочее место. Если сервер использует самоподписанный сертификат, соединение завершится ошибкой проверки подлинности — это защитное поведение, а не сбой платформы.

Авторизация, заголовки и прокси

Базовая авторизация и токены

Если сервер требует базовую аутентификацию, логин и пароль передаются третьим и четвёртым параметрами конструктора HTTPСоединение. Для авторизации по токену заголовок добавляется в запрос:

Запрос = Новый HTTPЗапрос(АдресРесурса);

Запрос.Заголовки.Вставить("Authorization", "Bearer " + Токен);

Работа через прокси

В корпоративной сети выход в интернет часто идёт через прокси-сервер. Его параметры задаются объектом ИнтернетПрокси:

Прокси = Новый ИнтернетПрокси(Истина);

Прокси.Установить("http", "proxy.local", 8080, "пользователь", "пароль");

Соединение = Новый HTTPСоединение(Сервер, 80, , , Прокси);

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

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

После загрузки стоит убедиться, что файл действительно получен и пригоден к использованию. Минимальный набор проверок: код состояния 200, файл существует на диске, его размер больше нуля. Если сервер отдаёт заголовок Content-Length, полезно сравнить его с фактическим размером.

Файл = Новый Файл(ИмяФайла);

Если Ответ.КодСостояния = 200 И Файл.Существует() И Файл.Размер() > 0 Тогда

// файл готов к обработке

КонецЕсли;

Типовые коды ответов, с которыми приходится сталкиваться: 301/302 — редирект (платформа по умолчанию не следует перенаправлению в старых релизах, адрес нужно взять из заголовка Location и повторить запрос), 401 — требуется авторизация, 403 — доступ запрещён, 404 — ресурс не найден, 5xx — ошибка на стороне сервера, имеет смысл повторить попытку позже.

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

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

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

200 (или 206 для частичной загрузки)

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

4xx/5xx — файл не получен, в выходном файле тело ошибки

Размер файла на диске
Норма

Больше нуля, совпадает с Content-Length

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

Нулевой размер или обрыв на середине

Содержимое файла
Норма

Ожидаемый формат (архив открывается, XML читается)

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

Внутри HTML-страница ошибки или редиректа

Частые ошибки и их причины

Наиболее распространённая проблема — путаница между адресом сервера и адресом ресурса. В конструктор HTTPСоединение передаётся только имя хоста без http:// и без пути; полный URL вызовет ошибку разбора адреса. Вторая частая ситуация — код 301 от сервера, который перевёл ресурс на HTTPS: запрос шёл по HTTP, а сервер отвечает редиректом.

Ещё одна группа ошибок связана с окружением: на сервере 1С не установлены корневые сертификаты, брандмауэр блокирует исходящие соединения от процесса rphost, учётная запись агента сервера не имеет доступа к прокси. Диагностируется это проверкой доступности адреса с той же машины, где выполняется код, под той же учётной записью.

Типичные ошибки
01
Передача полного URL в конструктор HTTPСоединения — ошибка разбора адреса; хост и путь нужно разделять
02
Отсутствие проверки КодСостояния — вместо данных сохраняется страница ошибки сервера
03
Игнорирование редиректа 301/302 — сохраняется пустой или служебный ответ вместо файла
04
Выполнение кода на клиенте при настроенной сети только на сервере — таймаут соединения
05
Отсутствие таймаута в соединении — зависание сеанса при недоступном сервере

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

Объект HTTPСоединение — не единственный вариант. Для интерактивной загрузки на клиенте есть метод глобального контекста ПолучитьФайлССервера и асинхронные аналоги, но они предназначены для передачи файла с сервера 1С на клиент, а не из интернета. Для простых случаев в толстом клиенте иногда используют COM-объект WinHttp.WinHttpRequest.5.1, однако это привязывает решение к Windows и не работает на Linux-сервере и в веб-клиенте.

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

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

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

Универсальный кроссплатформенный способ, работает на сервере и клиенте. Требует ручной обработки кодов ответа и редиректов.

WinHttpRequest через COM

Простая настройка прокси и редиректов из коробки, но только Windows и только там, где разрешены COM-объекты.

Асинхронные методы платформы

Не блокируют интерфейс при больших файлах; требуются современные релизы платформы и код с обещаниями.

FAQ

Как скачать файл, если сервер отвечает редиректом 301 или 302?

Прочитайте заголовок Location из ответа (Ответ.Заголовки.Получить("Location")), разберите полученный адрес на хост и путь, создайте новое соединение (часто уже HTTPS) и повторите запрос. Универсальная функция обычно делает это в цикле с ограничением числа перенаправлений, например до пяти.

Почему файл скачивается нулевого размера?

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

Как задать таймаут, чтобы сеанс не зависал?

Таймаут указывается пятым параметром конструктора HTTPСоединение в секундах, например: Новый HTTPСоединение(Сервер, 443, , , 60, ЗащищенноеСоединение). Для регламентных заданий разумно 30–120 секунд в зависимости от размера файла и качества канала.

Можно ли скачать файл в фоне, не блокируя работу пользователя?

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

Где выполнять загрузку — на клиенте или на сервере?

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

Как сохранить файл не на диск, а в хранилище значения?

Скачайте во временный файл, затем прочитайте его в двоичные данные: ДвоичныеДанные = Новый ДвоичныеДанные(ИмяФайла), поместите в Новый ХранилищеЗначения(ДвоичныеДанные, Новый СжатиеДанных(9)) и запишите в реквизит объекта. Временный файл после этого удалите.

Итог

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

Файл по HTTP в 1С скачивается связкой HTTPСоединение + HTTPЗапрос с сохранением ответа прямо в файл. Обязательны: разделение хоста и пути, защищённое соединение для HTTPS, проверка кода состояния и размера файла, обработка редиректов и таймаут.