Почему HTTPЗапрос в 1С возвращает код 301 и как настроить защищенное HTTPS-соединение?

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

При интеграции 1С со сторонними веб-сервисами через протокол HTTP разработчики нередко сталкиваются с ситуацией, когда ранее работавший запрос внезапно перестает возвращать данные, а метод HTTPОтвет.ПолучитьТелоКакСтроку() или код состояния возвращает 301 Moved Permanently. Разберем по шагам, почему возникает эта ошибка и как правильно перевести интеграцию на защищенное соединение.

Анализ проблемы: почему 1С возвращает код 301

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

Объект платформы HTTPСоединение по умолчанию не выполняет автоматический переход по редиректам, особенно если изменяется схема протокола с http:// на https://. В результате 1С просто получает ответ от сервера с кодом состояния 301 и заголовком ответа Location, в котором указан новый защищенный адрес.

Посмотрим на исходный пример кода, который отправлял запрос по протоколу HTTP на стандартный порт 80:


НомерТелефонаДляПередачиВЗапрос = "9275554147";
HTTPЗапрос = Новый HTTPЗапрос("/api.php?action=direct&subno=" + НомерТелефонаДляПередачиВЗапрос);
HTTPСоединение = Новый HTTPСоединение("potoksms.ru");    
HTTPОтвет = HTTPСоединение.Получить(HTTPЗапрос);

Возврат HTTPОтвет.ПолучитьТелоКакСтроку();

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

Основное решение: использование ЗащищенноеСоединениеOpenSSL

Для корректного обращения к сервисам, работающим по протоколу HTTPS, необходимо настроить защищенное соединение и указать порт 443. Рассмотрим подробнее, как модернизировать код в 1С:

  1. Создаем объект ЗащищенноеСоединениеOpenSSL, указав параметры сертификатов клиента и удостоверяющих центров операционной системы.
  2. Передаем объект защищенного соединения в конструктор HTTPСоединение седьмым параметром, а также явно указываем защищенный порт 443 вторым параметром.

Разберем рабочий пример реализации:


НомерТелефонаДляПередачиВЗапрос = "9275554147";
HTTPЗапрос = Новый HTTPЗапрос("/api.php?action=direct&subno=" + НомерТелефонаДляПередачиВЗапрос);

ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL(
    Новый СертификатКлиентаWindows(СпособВыбораСертификатаWindows.Авто),
    Новый СертификатыУдостоверяющихЦентровWindows()
);
        
HTTPСоединение = Новый HTTPСоединение("potoksms.ru", 443, , , , , ЗащищенноеСоединение);
HTTPОтвет = HTTPСоединение.Получить(HTTPЗапрос);

Возврат HTTPОтвет.ПолучитьТелоКакСтроку();

Если нет необходимости жестко привязываться к хранилищу Windows, в большинстве типовых конфигураций конструктор можно вызвать без параметров:


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

Решение проблемы: «Удаленный узел не прошел проверку»

При переносе кода на другой сервер или клиентский компьютер может возникнуть ошибка выполнения: «Ошибка работы с Интернет: Удаленный узел не прошел проверку». Проанализируем причины этой ошибки:

  1. Отсутствие корневого сертификата: В локальном хранилище операционной системы Windows отсутствует корневой или промежуточный сертификат удостоверяющего центра (УЦ), выдавшего SSL-сертификат удаленному сайту.
  2. Контекст службы сервера 1С: Если запрос выполняется в серверном коде (или в регламентном задании), проверка сертификатов выполняется под учетной записью системной службы (например, usr1cv8). Сертификаты должны быть установлены в хранилище «Локальный компьютер» (Local Computer), а не только «Текущий пользователь» (Current User).
  3. Некорректная дата и время: Если на сервере сбито системное время, срок действия SSL-сертификата будет определен как недействительный.

Для исправления ошибки выполните следующие действия:

  1. Откройте оснастку сертификатов Windows (certlm.msc) под правами администратора.
  2. Импортируйте корневой сертификат удаленного ресурса в папку «Доверенные корневые центры сертификации» (Trusted Root Certification Authorities).
  3. Если используется операционная система Linux, обновите общесистемный пакет доверенных сертификатов (ca-certificates).

Также можно явно передать файл цепочки доверенных сертификатов (формата .pem или .crt) прямо в конструктор 1С:


СертификатыУЦ = Новый СертификатыУдостоверяющихЦентров("C:\certs\ca_bundle.crt");
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, СертификатыУЦ);
HTTPСоединение = Новый HTTPСоединение("potoksms.ru", 443, , , , , ЗащищенноеСоединение);

Альтернативный вариант: программная обработка перенаправлений

Если сервис может менять адреса динамически, рекомендуется обрабатывать код состояния в коде и считывать новый путь из заголовков ответа:


Если HTTPОтвет.КодСостояния = 301 ИЛИ HTTPОтвет.КодСостояния = 302 Тогда
    НовыйАдрес = HTTPОтвет.Заголовки.Получить("Location");
    // Выполняем повторный запрос по полученному адресу
КонецЕсли;

Таким образом, переход на ЗащищенноеСоединениеOpenSSL с портом 443 и обеспечение доверия к SSL-сертификату на уровне операционной системы позволяют стабильно отправлять запросы и получать корректные ответы от веб-сервисов.

← На главную