Как исправить ошибку "Couldn't resolve host name" при HTTP-запросе из 1С?

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

При разработке интеграций с внешними системами в 1С часто возникает необходимость отправлять HTTP-запросы. Одним из распространенных сценариев является взаимодействие с HTTP-сервисами. Иногда возникает ситуация, когда запрос успешно выполняется из сторонних инструментов, таких как Postman (или его аналога на платформе 1С), но из 1С выдает ошибку "Couldn't resolve host name" — пригодится консоль запросов и кода для 1С. В этой статье мы подробно разберем, почему возникает эта ошибка и как ее эффективно устранить, основываясь на практическом примере.

Анализируем проблему: Запрос из Postman работает, из 1С — нет

Представим, что у нас есть HTTP-сервис, который успешно вызывается из Postman или специальной обработки для тестирования http-сервисов по следующему адресу и с телом запроса:

URL: https://web.srvteam.net:4001/c23910-03/hs/lic/checklic (подобные запросы часто используются в интеграциях с веб-регистраторами для проверки лицензий)

Тело запроса (JSON):


{
"Kontr": "ываыва",
"YurLico": true,
"INN": "7987987978  ",
"Pin": "9012-1974-1727-4325",
"Phone": "+7(324)234-",
"EMAIL": "pos@mail.ru",
"SerialNumberHD": -1609980586
}

В 1С же мы пытаемся отправить аналогичный запрос, используя следующий код (поможет пошаговая отладка кода 1С в режиме «Предприятие»):


// Предполагается, что ТелоЗапроса уже сформировано через ЗаписьJSON.Закрыть()
ТелоЗапроса = ЗаписьJson.Закрыть();

// Исходный код, вызывающий ошибку
HTTP = Новый HTTPСоединение("https://web.srvteam.net/c23910-03",4001,"ad","",,, Новый ЗащищенноеСоединениеOpenSSL());
ТекстЗапроса = "hs/lic/checklic";
Запрос = Новый HTTPЗапрос(ТекстЗапроса, Новый Соответствие());
Запрос.УстановитьТелоИзСтроки(ТелоЗапроса);
ОтветHTTP = HTTP.ОтправитьДляОбработки(Запрос);

После выполнения этого кода платформа 1С выдает ошибку:

Ошибка работы с Интернет: Couldn't resolve host name

Выясняем причину ошибки "Couldn't resolve host name"

Ошибка "Couldn't resolve host name" означает, что операционная система, на которой выполняется 1С, не смогла преобразовать указанное доменное имя в IP-адрес. Проще говоря, 1С не может найти сервер по имени, которое ей передали. Разберем, почему это происходит в нашем случае:

  1. Неправильное разделение адреса между объектами HTTPСоединение и HTTPЗапрос:

    Ключевая проблема кроется в том, как мы сконструировали объект HTTPСоединение. Он предназначен для установки соединения с конкретным сервером и портом. Параметры конструктора Новый HTTPСоединение(<Сервер>, <Порт>, <Пользователь>, <Пароль>, ...) ожидают:

    • <Сервер>: Только доменное имя (например, web.srvteam.net) или IP-адрес.
    • <Порт>: Числовой номер порта (например, 4001).

    В нашем исходном коде мы передали в качестве первого параметра "https://web.srvteam.net/c23910-03". Здесь мы видим несколько ошибок:

    • Мы указали протокол https://. Наличие протокола в параметре <Сервер> заставляет 1С пытаться разрешить весь этот текст как имя хоста, что приводит к ошибке. Протокол для защищенного соединения уже указан через последний параметр Новый ЗащищенноеСоединениеOpenSSL().
    • Мы включили часть пути /c23910-03 в параметр <Сервер>. Часть пути всегда должна передаваться в объект HTTPЗапрос, а не в HTTPСоединение.

    Таким образом, 1С пыталась найти хост с именем "https://web.srvteam.net/c23910-03", что, конечно же, не является корректным доменным именем или IP-адресом.

  2. Другие потенциальные причины (менее вероятные в данном случае, но важные для общего понимания):
    • Проблемы с DNS-серверами: Если компьютер, на котором выполняется запрос, не может обратиться к DNS-серверу или DNS-сервер не может разрешить доменное имя, возникнет та же ошибка. Убедитесь в корректности настроек DNS.
    • Настройки прокси-сервера: Если доступ в интернет осуществляется через прокси-сервер, 1С может требовать его настройки.
    • Блокировка брандмауэром/антивирусом: Иногда брандмауэр или антивирусное ПО могут блокировать исходящие сетевые соединения для приложения 1С.

Разбираем решение проблемы по шагам

Теперь, когда мы понимаем причину, давайте исправим код и посмотрим, как он должен выглядеть.

Шаг 1: Корректно разделяем URL на составляющие

Вспоминаем наш полный URL из Postman: https://web.srvteam.net:4001/c23910-03/hs/lic/checklic

Правильно разделяем его на компоненты для 1С:

Шаг 2: Корректируем создание объекта HTTPСоединение

Из объекта HTTPСоединение мы должны убрать протокол https:// и всю часть пути. Вместо этого передаем только доменное имя и порт:


HTTP = Новый HTTPСоединение("web.srvteam.net", 4001, "ad", "",,, Новый ЗащищенноеСоединениеOpenSSL());

Здесь:

Шаг 3: Корректируем создание объекта HTTPЗапрос

Объект HTTPЗапрос должен содержать полный относительный путь к ресурсу на сервере, начиная с корневого каталога HTTP-сервиса:

ТекстЗапроса = "c23910-03/hs/lic/checklic";

Это полная строка, которая следует за комбинацией "доменное имя:порт" в исходном URL.

Шаг 4: Настройка авторизации (Basic Auth)

В нашем примере, как было уточнено в обсуждении, используется Basic Auth (базовая авторизация). В 1С есть два основных способа настроить Basic Auth:

  1. Через параметры конструктора HTTPСоединение: Это наиболее простой способ, который мы уже использовали в исправленном коде. Мы передали "ad" в качестве имени пользователя и пустую строку "" в качестве пароля.
    
    HTTP = Новый HTTPСоединение("web.srvteam.net", 4001, "ad", "",,, Новый ЗащищенноеСоединениеOpenSSL());
    

    Если бы был пароль, он бы указывался на месте второй пустой строки: Новый HTTPСоединение(<Сервер>, <Порт>, <Пользователь>, <Пароль>, ...).

  2. Через заголовки HTTP-запроса: Этот способ дает больше контроля и может быть полезен, если вы хотите, например, динамически формировать токен авторизации. Вам нужно будет сформировать строку "Пользователь:Пароль", закодировать ее в Base64 и добавить в заголовки запроса.
    
    // Предполагаем, что у нас есть функция для Base64 кодирования
    Функция База64Кодировать(СтрокаДанных)
        // Пример упрощенной реализации (может отличаться в зависимости от платформы)
        // В 1С 8.3.16+ есть ПолучитьBase64СтрокуИзДвоичныхДанных()
        ДвоичныеДанные = Новый ДвоичныеДанные(СтрокаДанных, КодировкаТекста.UTF8);
        Возврат Base64Строка(ДвоичныеДанные); // Base64Строка() - встроенная функция
    КонецФункции
    
    // Формируем строку авторизации
    СтрокаДляКодирования = "ad:"; // Если пароль пустой
    // СтрокаДляКодирования = "Логин:Пароль"; // Если есть пароль
    
    СтрокаАвторизацииBase64 = База64Кодировать(СтрокаДляКодирования);
    
    // Создаем соответствие для заголовков
    Заголовки = Новый Соответствие();
    Заголовки.Вставить("Authorization", "Basic " + СтрокаАвторизацииBase64);
    
    // Создаем HTTPЗапрос с заголовками
    Запрос = Новый HTTPЗапрос(ТекстЗапроса, Заголовки);
    

    В более современных версиях 1С (начиная с 8.3.16) для кодирования в Base64 можно использовать:

    
    СтрокаДляКодирования = "ad:"; // Например
    ДвоичныеДанныеЛогинПароль = Новый ДвоичныеДанные(СтрокаДляКодирования, КодировкаТекста.UTF8);
    СтрокаАвторизацииBase64 = ПолучитьBase64СтрокуИзДвоичныхДанных(ДвоичныеДанныеЛогинПароль);
    

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

Финальный рабочий код

С учетом всех исправлений, рабочий код для выполнения HTTP-запроса из 1С будет выглядеть следующим образом:


// Предполагается, что ТелоЗапроса уже сформировано через ЗаписьJSON.Закрыть()
ТелоЗапроса = ЗаписьJson.Закрыть();

// Создаем HTTP-соединение с корректными параметрами
// 'web.srvteam.net' - только доменное имя сервера
// 4001 - порт
// 'ad' - имя пользователя для Basic Auth
// '' - пустой пароль для Basic Auth
// Новый ЗащищенноеСоединениеOpenSSL() - для работы по HTTPS
HTTP = Новый HTTPСоединение("web.srvteam.net", 4001, "ad", "",,, Новый ЗащищенноеСоединениеOpenSSL());

// Указываем полный относительный путь к ресурсу HTTP-сервиса
ТекстЗапроса = "c23910-03/hs/lic/checklic";

// Создаем HTTP-запрос
Запрос = Новый HTTPЗапрос(ТекстЗапроса, Новый Соответствие());

// Устанавливаем тело запроса, сформированное в формате JSON
Запрос.УстановитьТелоИзСтроки(ТелоЗапроса);

// Отправляем запрос и получаем ответ
ОтветHTTP = HTTP.ОтправитьДляОбработки(Запрос);

// Далее можно обработать полученный ОтветHTTP
// Например, получить статус: ОтветHTTP.КодСостояния
// Или получить тело ответа: ОтветHTTP.ПолучитьТелоКакСтроку()

Дополнительные рекомендации по отладке HTTP-запросов в 1С

Давайте рассмотрим, какие еще методы мы можем использовать для диагностики и решения проблем с HTTP-запросами в 1С:

  1. Проверка сетевого соединения:
    • Убедитесь, что сервер 1С (или клиент, если запрос выполняется на клиенте) имеет доступ к целевому доменному имени/IP-адресу и порту. Можно использовать команду ping web.srvteam.net или telnet web.srvteam.net 4001 из командной строки.
  2. Журнал регистрации 1С:
    • Для отладки параметров запроса мы можем записывать их в журнал регистрации. Это помогает понять, какие данные фактически отправляются, а также какие ошибки возникают на более низком уровне. Для этой задачи есть инструмент уведомления об ошибках в Telegram.
    • 
      // Пример записи в журнал перед отправкой запроса
      ЗаписьЖурналаРегистрации("HTTP-запрос", УровеньЖурналаРегистрации.Информация,,, "Отправка запроса на " + ТекстЗапроса + ". Тело: " + ТелоЗапроса);
      
  3. Средства мониторинга сети:
    • Использование программ мониторинга сети, таких как Wireshark, позволяет отслеживать HTTP-трафик между клиентом (1С) и сервером. Это дает возможность увидеть полный запрос и ответ, включая заголовки и тело, что очень полезно для диагностики проблем на сетевом уровне — для этого подойдёт автоматизация сбора и анализа HTTP-запросов.
  4. Ошибки SSL/TLS:
    • Если сервер использует самоподписанный SSL-сертификат или сертификат устарел/недоверен, это также может вызывать проблемы с ЗащищенноеСоединениеOpenSSL(). В некоторых случаях может потребоваться использование СертификатКлиентаWindows() или СертификатыУдостоверяющихЦентровWindows() в конструкторе ЗащищенноеСоединениеOpenSSL для корректной работы с сертификатами, или установка сертификата в доверенные хранилища операционной системы.

Соблюдение этих рекомендаций и внимательное разделение компонентов URL между HTTPСоединение и HTTPЗапрос помогут вам избежать распространенных ошибок и эффективно работать с HTTP-запросами в 1С. Для более глубокого изучения темы пригодится интерактивный курс по работе с HTTP-запросами.

← На главную