Как в 1С скачать файл по ссылке HTTPS и избежать ошибки 301 Moved Permanently?

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

При интеграции 1С с внешними веб-сервисами и сайтами разработчики часто сталкиваются с ситуацией, когда при попытке скачать файл сохраняется не сам целевой документ (например, XML или ZIP), а HTML-страница с ошибкой 301 Moved Permanently или формой авторизации. Разберем по шагам причины такого поведения платформы и рассмотрим правильные варианты реализации загрузки файлов.

Анализируем причину возникновения ошибки 301

Код состояния HTTP 301 Moved Permanently означает, что запрашиваемый ресурс был окончательно перемещен на другой адрес. В платформе 1С объект HTTPСоединение по умолчанию не переходит по редиректам автоматически. Если сервер отправляет перенаправление, 1С добросовестно сохраняет тело ответа этого перенаправления в указанный файл на диске.

В веб-разработке и современных сервисах редирект 301 чаще всего возникает в двух случаях:

  1. Попытка обращения по обычному HTTP вместо защищенного HTTPS: веб-сервер принудительно перенаправляет незащищенное подключение (порт 80) на защищенный протокол (порт 443). Если в конструкторе HTTPСоединение не инициализирован параметр защищенного соединения, платформа 1С стучится по HTTP и получает ответ 301.
  2. Перенаправление на страницу авторизации: если ресурс закрыт паролем, а платформа не передала нужные сессионные данные (cookies или токен), сервер возвращает ответ с перенаправлением на форму логина.

Решение 1. Правильная настройка HTTPS через ЗащищенноеСоединениеOpenSSL

Если файл находится в публичном доступе, но доступен только по протоколу HTTPS, необходимо явно указать защищенный режим при создании объекта HTTPСоединение. Для этого используется объект ЗащищенноеСоединениеOpenSSL.

Рассмотрим пример правильного создания защищенного соединения и скачивания файла:


Сервер = "office7.auto.ru";
ПутьКФайлуНаСервере = "/v2/products/all/sales/upload/cars/help/get/";
ПутьДляСохранения = "C:\Temp\avtoru_help.zip";

// Инициализируем защищенное соединение для протокола HTTPS
Защита = Новый ЗащищенноеСоединениеOpenSSL();

// Передаем параметры: Сервер, Порт (443 для HTTPS), Логин, Пароль, Прокси, Таймаут, ЗащищенноеСоединение
Соединение = Новый HTTPСоединение(Сервер, 443, , , , 30, Защита);

// Выполняем GET-запрос и сохраняем файл
HTTPЗапрос = Новый HTTPЗапрос(ПутьКФайлуНаСервере);
Ответ = Соединение.Получить(HTTPЗапрос, ПутьДляСохранения);

Если Ответ.КодСостояния = 200 Тогда
    // Файл успешно получен и сохранен на диск
Иначе
    // Обрабатываем другие коды состояния (например, 404 или 403)
КонецЕсли;

Обратите внимание: указание порта 443 и передача объекта ЗащищенноеСоединениеOpenSSL исключают промежуточный редирект с незащищенного протокола, позволяя напрямую скачать файл.

Решение 2. Корректная авторизация: cookies против базовой аутентификации

Частая ошибка разработчиков — передача учетных данных сайта в параметры «Пользователь» и «Пароль» конструктора HTTPСоединение. Эти параметры предназначены исключительно для протокольной аутентификации HTTP Basic / Digest. Если веб-сайт использует стандартную веб-авторизацию с формами входа, такие параметры сервером игнорируются.

Для скачивания файлов с ресурсов, требующих веб-авторизации, необходимо реализовать двухэтапный процесс:

  1. Выполнение запроса авторизации: отправляем POST-запрос с учетными данными на URL аутентификации сервиса и считываем полученные сессионные куки из заголовка Set-Cookie.
  2. Передача сессионных данных: добавляем полученные куки в заголовок Cookie последующего GET-запроса на скачивание файла.

Посмотрим на пример реализации работы с заголовками авторизации:


Защита = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение("office7.auto.ru", 443, , , , 30, Защита);

// Шаг 1. Формируем запрос авторизации (передаем тело и тип контента)
ЗапросАвторизации = Новый HTTPЗапрос("/auth/login");
ЗапросАвторизации.Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");
ЗапросАвторизации.УстановитьТелоИзСтроки("login=my_user&password=my_password", "UTF-8");

ОтветАвторизации = Соединение.ОтправитьДляОбработки(ЗапросАвторизации);

// Извлекаем сессионную куку из ответа
Куки = "";
Если ОтветАвторизации.Заголовки.Свойство("Set-Cookie") Тогда
    Куки = ОтветАвторизации.Заголовки.Получить("Set-Cookie");
КонецЕсли;

// Шаг 2. Запрашиваем закрытый файл с передачей сессии
ЗапросФайла = Новый HTTPЗапрос("/products/all/sales/upload/cars/catalog/");
Если ЗначениеЗаполнено(Куки) Тогда
    ЗапросФайла.Заголовки.Вставить("Cookie", Куки);
КонецЕсли;

ПутьДляСохранения = "C:\Temp\avtoru_catalog.xml";
ОтветФайла = Соединение.Получить(ЗапросФайла, ПутьДляСохранения);

Решение 3. Программная обработка редиректов (Location)

Если сервер возвращает коды перенаправления 301, 302, 307 или 308 по логике своей работы, платформе 1С необходимо явно обработать заголовок Location.

Разберем алгоритм ручной обработки редиректа:


Защита = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение("office7.auto.ru", 443, , , , 30, Защита);
ТекущийПуть = "/products/all/sales/upload/cars/catalog/";
ПутьДляСохранения = "C:\Temp\result.xml";

МаксРедиректов = 5;
Счетчик = 0;

Пока Счетчик < МаксРедиректов Цикл
    HTTPЗапрос = Новый HTTPЗапрос(ТекущийПуть);
    Ответ = Соединение.Получить(HTTPЗапрос, ПутьДляСохранения);
    
    // Проверяем, вернул ли сервер код перенаправления
    Если Ответ.КодСостояния = 301 ИЛИ Ответ.КодСостояния = 302 ИЛИ Ответ.КодСостояния = 307 Тогда
        Если Ответ.Заголовки.Свойство("Location") Тогда
            НовыйURL = Ответ.Заголовки.Получить("Location");
            // Если перенаправление ведет на относительный путь
            ТекущийПуть = НовыйURL;
            Счетчик = Счетчик + 1;
        Иначе
            Прервать;
        КонецЕсли;
    ИначеЕсли Ответ.КодСостояния = 200 Тогда
        // Файл успешно получен
        Прервать;
    Иначе
        // Обработка ошибок сервера
        Прервать;
    КонецЕсли;
КонецЦикла;

Ограничения функции КопироватьФайл

Метод КопироватьФайл() можно применять исключительно для простой прямой загрузки общедоступных файлов по прямым ссылкам без авторизации и сложных редиректов. Данный метод не предоставляет доступа к управлению заголовками (таким как Cookie или Authorization), не позволяет задать таймауты и не возвращает детальные HTTP-коды при возникновении сетевых ошибок. Для надежного обмена данными в промышленных решениях рекомендуется всегда использовать объект HTTPСоединение.

← На главную