При разработке интеграций с внешними системами в 1С часто возникает необходимость отправлять HTTP-запросы. Одним из распространенных сценариев является взаимодействие с HTTP-сервисами. Иногда возникает ситуация, когда запрос успешно выполняется из сторонних инструментов, таких как Postman (или его аналога на платформе 1С), но из 1С выдает ошибку "Couldn't resolve host name" — пригодится консоль запросов и кода для 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" означает, что операционная система, на которой выполняется 1С, не смогла преобразовать указанное доменное имя в IP-адрес. Проще говоря, 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-адресом.
Теперь, когда мы понимаем причину, давайте исправим код и посмотрим, как он должен выглядеть.
Вспоминаем наш полный URL из Postman: https://web.srvteam.net:4001/c23910-03/hs/lic/checklic
Правильно разделяем его на компоненты для 1С:
web.srvteam.net (без протокола)4001c23910-03/hs/lic/checklic (весь путь, начиная с первого сегмента после порта)HTTPСоединениеИз объекта HTTPСоединение мы должны убрать протокол https:// и всю часть пути. Вместо этого передаем только доменное имя и порт:
HTTP = Новый HTTPСоединение("web.srvteam.net", 4001, "ad", "",,, Новый ЗащищенноеСоединениеOpenSSL());
Здесь:
"web.srvteam.net" – корректное доменное имя сервера.4001 – номер порта."ad" – имя пользователя для Basic Auth (было указано в исходном коде, как и пустой пароль "").Новый ЗащищенноеСоединениеOpenSSL() – указывает, что соединение должно быть по протоколу HTTPS.HTTPЗапросОбъект HTTPЗапрос должен содержать полный относительный путь к ресурсу на сервере, начиная с корневого каталога HTTP-сервиса:
ТекстЗапроса = "c23910-03/hs/lic/checklic";
Это полная строка, которая следует за комбинацией "доменное имя:порт" в исходном URL.
В нашем примере, как было уточнено в обсуждении, используется Basic Auth (базовая авторизация). В 1С есть два основных способа настроить Basic Auth:
HTTPСоединение: Это наиболее простой способ, который мы уже использовали в исправленном коде. Мы передали "ad" в качестве имени пользователя и пустую строку "" в качестве пароля.
HTTP = Новый HTTPСоединение("web.srvteam.net", 4001, "ad", "",,, Новый ЗащищенноеСоединениеOpenSSL());
Если бы был пароль, он бы указывался на месте второй пустой строки: Новый HTTPСоединение(<Сервер>, <Порт>, <Пользователь>, <Пароль>, ...).
// Предполагаем, что у нас есть функция для 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С:
ping web.srvteam.net или telnet web.srvteam.net 4001 из командной строки.
// Пример записи в журнал перед отправкой запроса
ЗаписьЖурналаРегистрации("HTTP-запрос", УровеньЖурналаРегистрации.Информация,,, "Отправка запроса на " + ТекстЗапроса + ". Тело: " + ТелоЗапроса);
ЗащищенноеСоединениеOpenSSL(). В некоторых случаях может потребоваться использование СертификатКлиентаWindows() или СертификатыУдостоверяющихЦентровWindows() в конструкторе ЗащищенноеСоединениеOpenSSL для корректной работы с сертификатами, или установка сертификата в доверенные хранилища операционной системы.Соблюдение этих рекомендаций и внимательное разделение компонентов URL между HTTPСоединение и HTTPЗапрос помогут вам избежать распространенных ошибок и эффективно работать с HTTP-запросами в 1С. Для более глубокого изучения темы пригодится интерактивный курс по работе с HTTP-запросами.