Как реализовать скачивание файла по HTTP-ссылке с параметрами в 1С

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

В процессе интеграции 1С с внешними веб-сервисами и базами данных разработчики часто сталкиваются с необходимостью автоматического скачивания файлов (отчетов, прайс-листов, реестров). Часто в качестве рабочего примера предоставляется готовый код на других языках программирования, например, на C#. Перенос этой логики в 1С может вызвать определенные трудности, связанные со спецификой работы платформы 1С с HTTP-протоколом.

В этой статье мы подробно разберем, как перенести рабочий пример скачивания файла с C# в 1С. Мы проанализируем частые ошибки разработчиков, такие как путаница между параметрами URL и заголовками запроса, проблемы с кодированием кириллических символов и управление таймаутом соединения при длительной генерации файлов на стороне сервера. Также мы рассмотрим несколько способов реализации задачи — от простых однострочных команд до профессионального кроссплатформенного подхода.

Анализ исходной задачи и примера на C#

Рассмотрим пример кода на C#, который выполняет скачивание файла:


private void button1_Click(object sender, EventArgs e)
{
    WebClient webClient = new WebClient();
    string link = @"http://dezvgr2/pls/info/REESTR_SOB_TO_1C.run?rep_user=TVERETINA&p_com=30274&p_reestr_format=xls&p_action=Start";
    string downloadFileName = System.IO.Path.GetFileName("test.xls");
    webClient.DownloadFile(new Uri(link), @"F:\tmp\test\" + downloadFileName);
}

Этот код выполняет классический GET-запрос по указанному URL-адресу. Параметры запроса (rep_user, p_com, p_reestr_format и p_action) передаются непосредственно в строке адреса (Query Parameters). На стороне веб-сервера (в данном случае это шлюз Oracle PL/SQL Gateway /pls/...) эти параметры обрабатываются, формируется отчет в формате XLS и отдается клиенту в виде бинарного потока. Наша задача — повторить это поведение в 1С.

Типичные ошибки при реализации в 1С

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

  1. Передача параметров запроса в заголовках HTTP (Header). Это одна из самых распространенных ошибок. Разработчик пытается передать параметры отчета с помощью метода HTTPЗапрос.Заголовки.Вставить(). Заголовки HTTP предназначены для метаданных (например, тип контента, авторизация, настройки кэширования). Параметры же отчета должны находиться в самой строке URL-запроса (для GET) или в теле запроса (для POST). Если передать их в заголовках, принимающий сервер их просто проигнорирует и вернет дефолтную страницу настроек.
  2. Проблема с кодировкой кириллических параметров. Если в параметрах запроса передаются русские буквы (например, p_action=Пуск), сервер может их не понять из-за различий в кодировках (UTF-8, Windows-1251, ISO-8859-1). Символы кириллицы в строке URL должны быть обязательно закодированы по стандарту RFC 3986 (Percent-encoding).
  3. Короткий таймаут соединения. Если файл на стороне веб-сервера формируется долго (несколько минут), то стандартное HTTP-соединение в 1С может прерваться по таймауту, не дождавшись ответа. Таймаут необходимо контролировать вручную при инициализации соединения.

Теперь разберем проверенные способы реализации скачивания файла в 1С по шагам.

Способ 1. Кроссплатформенный и надежный метод через HTTPСоединение (Рекомендуется)

Использование встроенных объектов HTTPСоединение и HTTPЗапрос является стандартом современной разработки. Этот код будет стабильно работать как на Windows, так и на Linux-серверах, а также в веб-клиенте.

Выясним причину, почему в 1С нельзя просто передать полную ссылку в соединение. Дело в том, что конструктор HTTPСоединение принимает в качестве первого параметра только имя сервера (домен или IP-адрес), а сам путь к ресурсу и параметры запроса передаются в объект HTTPЗапрос.

Разберем готовый шаблон кода для скачивания файла:


// Определение путей и параметров запроса
СерверАдрес = "dezvgr2";
ИмяВходящегоФайла = "F:\tmp\test\test.xls";

// Формируем параметры запроса. Если есть русские буквы, обязательно кодируем их!
ПараметрДействия = КодироватьСтроку("Start", СпособКодированияСтроки.КодировкаURL);
ПараметрПользователя = КодироватьСтроку("TVERETINA", СпособКодированияСтроки.КодировкаURL);

// Собираем путь ресурса с параметрами
ПутьЗапроса = "/pls/info/REESTR_SOB_TO_1C.run"
            + "?rep_user=" + ПараметрПользователя
            + "&p_com=30274"
            + "&p_reestr_format=xls"
            + "&p_action=" + ПараметрДействия;

// Создаем HTTP-соединение. 
// Шестым параметром устанавливаем таймаут ожидания сервера в секундах (например, 600 секунд = 10 минут)
// Это критически важно, если файл формируется долго!
Соединение = Новый HTTPСоединение(СерверАдрес, , , , , 600);

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

Попытка
    // Отправляем GET-запрос на сервер
    HTTPОтвет = Соединение.Получить(HTTPЗапрос);
    
    Если HTTPОтвет.КодСостояния = 200 Тогда
        // Получаем двоичные данные из тела ответа и записываем их в файл
        ДвоичныеДанныеФайла = HTTPОтвет.ПолучитьТелоКакДвоичныеДанные();
        ДвоичныеДанныеФайла.Записать(ИмяВходящегоФайла);
        Сообщить("Файл успешно скачан и сохранен: " + ИмяВходящегоФайла);
    Иначе
        Сообщить("Ошибка сервера! Код состояния: " + HTTPОтвет.КодСостояния);
        Сообщить("Ответ сервера: " + HTTPОтвет.ПолучитьТелоКакСтроку());
    КонецЕсли;
Исключение
    Сообщить("Не удалось установить соединение с сервером: " + ОписаниеОшибки());
КонецПопытки;

В этом примере мы использовали метод Получить() для отправки классического GET-запроса. Если принимающий веб-сервер требует передачи параметров методом POST, мы можем использовать метод ОтправитьДляОбработки(), передав параметры в теле запроса, либо оставить параметры в строке запроса в зависимости от требований API сервера.

Способ 2. Быстрое скачивание через КопироватьФайл

Если вам не требуется тонкая настройка заголовков, авторизации или таймаутов, а нужно просто "скачать файл по ссылке как в браузере", можно воспользоваться глобальным методом платформы КопироватьФайл. Данный метод поддерживает схемы адресации http и https.

Посмотрим на пример его использования:


СсылкаНаФайл = "http://dezvgr2/pls/info/REESTR_SOB_TO_1C.run?rep_user=TVERETINA&p_com=30274&p_reestr_format=xls&p_action=Start";
ПутьСохранения = "F:\tmp\test\test.xls";

Попытка
    // Платформа сама установит HTTP-соединение, отправит GET-запрос и сохранит результат на диск
    КопироватьФайл(СсылкаНаФайл, ПутьСохранения);
    Сообщить("Файл успешно скопирован.");
Исключение
    Сообщить("Произошла ошибка при копировании файла: " + ОписаниеОшибки());
КонецПопытки;

Важное примечание: при использовании этого метода в адресах необходимо указывать только прямые слеши (/), а не обратные (\). На веб-клиенте этот метод работает только с локальными файлами и требует предварительного подключения расширения работы с файлами.

Способ 3. Использование COM-объектов (Только для Windows-серверов)

В старых конфигурациях или специфических сценариях администрирования на Windows-платформах разработчики часто используют компоненты операционной системы через механизм COM-соединения. Для этого подходят объекты WinHttp.WinHttpRequest.5.1 и ADODB.Stream.

Рассмотрим, как это выглядит в коде 1С:


ИмяВходящегоФайла = "F:\tmp\test\test.xls";
Ссылка = "http://dezvgr2/pls/info/REESTR_SOB_TO_1C.run?rep_user=TVERETINA&p_com=30274&p_reestr_format=xls&p_action=Start";

Попытка
    // Инициализация WinHTTP запроса
    WinHttp = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
    WinHttp.Open("GET", Ссылка, Ложь); // Ложь указывает на синхронный режим ожидания
    WinHttp.Send();
    
    Если WinHttp.Status = 200 Тогда
        // Запись бинарного потока ответа на диск через ADODB.Stream
        Stream = Новый COMОбъект("ADODB.Stream");
        Stream.Type = 1; // Binary data
        Stream.Mode = 3; // Read/Write
        Stream.Open();
        Stream.Write(WinHttp.ResponseBody); 
        Stream.SaveToFile(ИмяВходящегоФайла, 2); // 2 - перезаписывать существующий файл
        Stream.Close();
        
        Сообщить("Файл успешно сохранен через COM.");
    Иначе
        Сообщить("Ошибка HTTP: " + WinHttp.Status + " " + WinHttp.StatusText);
    КонецЕсли;
Исключение
    Сообщить("Ошибка при работе с COM-объектами: " + ОписаниеОшибки());
КонецПопытки;

Предупреждение: Мы настоятельно рекомендуем избегать использования COM-объектов в современном коде 1С. Такой код не запустится, если ваша база 1С будет перенесена на сервер под управлением Linux, а также вызовет сложности при переходе на новые версии платформы.

Резюме и рекомендации

Для реализации скачивания файлов по HTTP-ссылкам в 1С всегда отдавайте предпочтение Способу 1 (HTTPСоединение). Он обеспечивает:

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

← На главную