Как подключиться к веб-сервису, если в WSDL указан неверный порт или адрес?

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

При работе с внешними веб-сервисами, особенно опубликованными на нестандартных портах (отличных от 80 для HTTP и 443 для HTTPS), разработчики часто сталкиваются с ситуацией, когда файл описания WSDL доступен по ссылке, но при попытке вызова методов возникает ошибка подключения. Проанализируем ситуацию: если мы откроем текст WSDL в браузере и заглянем в секцию soap:address location, то можем обнаружить, что там указан адрес без порта или с неверным хостом. Это происходит потому, что платформа 1С при динамической генерации WSDL ориентируется на заголовки пришедшего HTTP-запроса, и если веб-сервер (например, IIS или Apache) настроен через проброс портов или реверс-прокси, информация о реальном порте может потеряться.

В данной статье мы разберем несколько способов решения этой проблемы: от «быстрого исправления» через локальный файл до архитектурно правильного переопределения точки подключения в коде 1С.

Причина возникновения проблемы: почему в WSDL неверный адрес?

Выясним причину, по которой 1С генерирует некорректный атрибут location. Когда клиент запрашивает ?wsdl, расширение веб-сервиса 1С берет имя сервера и порт из HTTP-заголовка Host. Рассмотрим типичный случай: веб-сервер слушает порт 8080, но снаружи он опубликован через NAT как порт 80. Или наоборот: IIS работает на порту 80, а внешние запросы приходят на 8002. Если администратор не настроил корректную трансляцию заголовков, 1С «выплеснет» в WSDL внутренний адрес, к которому внешний клиент не сможет достучаться. В итоге объект WSОпределения создается успешно, но объект WSПрокси при попытке вызова метода будет ломиться по неверному адресу.

Решение 1: Использование локального WSDL-файла и протокола file://

Это самый оперативный способ, если у вас нет доступа к настройкам веб-сервера. Суть метода заключается в том, чтобы скачать текст WSDL, программно заменить в нем строку адреса на правильную, сохранить во временный файл и загрузить определение уже из этого файла. Разберем по шагам, как это реализовать в коде.

Для начала нам необходимо получить текст описания сервиса. Мы можем сделать это обычным HTTP-запросом или загрузить из константы, если адрес меняется редко. После получения текста мы правим порт в узле location.

Посмотрим на пример реализации функции подключения:


Функция ПодключитьсяКСервисуСПомощьюФайла() Экспорт
    // Получаем настройки
    Логин = "Robot";
    Пароль = "password";
    // Допустим, мы заранее получили текст WSDL и сохранили в переменную WSDLТекст
    WSDLТекст = ПолучитьТекстWSDLСервера(); 

    // Путь к временному файлу
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xml");
    
    // Важный нюанс: 1С требует для протокола file:// использование прямых слешей
    АдресДляОпределения = СтрЗаменить(ИмяВременногоФайла, "\", "/");
    АдресДляОпределения = "file://" + АдресДляОпределения;
    
    // Записываем исправленный WSDL (предполагается, что в WSDLТекст уже заменен адрес)
    ТекстДок = Новый ТекстовыйДокумент();
    ТекстДок.УстановитьТекст(WSDLТекст);
    ТекстДок.Записать(ИмяВременногоФайла);
    
    Попытка
        // Создаем определение из локального файла
        Определение = Новый WSОпределения(АдресДляОпределения, Логин, Пароль);
        
        ПространствоИмен = "http://www.your-service.ru/Exchange";
        Прокси = Новый WSПрокси(Определение, ПространствоИмен, "Service_Name", "Port_Name");
        
        Прокси.Пользователь = Логин;
        Прокси.Пароль = Пароль;
        
        Возврат Прокси;
    Исключение
        ЗаписьЖурналаРегистрации("Ошибка подключения к WS", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
        Возврат Неопределено;
    КонецПопытки;
КонецФункции

Важно: При использовании этого метода помните, что если ваш WSDL содержит импорты схем (тег xsd:import) с относительными путями, 1С не сможет их найти рядом с временным файлом в папке temp. В этом случае метод с файлом может выдать ошибку при создании объекта WSОпределения.

Решение 2: Программное переопределение точки подключения (Endpoint)

Мало кто знает, но в платформе 1С предусмотрен штатный механизм для решения этой проблемы без манипуляций с файловой системой. Мы можем загрузить WSОпределения по реальному URL (даже если внутри location кривой), а при создании WSПрокси явно указать, куда на самом деле нужно отправлять запросы.

Проанализируем параметры конструктора Новый WSПрокси. У него есть пятый параметр — ТочкаПодключения. Если мы передадим туда правильный URL с нужным портом, 1С проигнорирует тот адрес, который был прописан внутри WSDL.

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


// 1. Создаем определение по реальному адресу (где лежит WSDL)
// Порт здесь нужен только для того, чтобы скачать сам XML файл описания
АдресWSDL = "http://192.168.1.10:8002/base/ws/service.1cws?wsdl";
Определение = Новый WSОпределения(АдресWSDL, Логин, Пароль);

// 2. Определяем параметры сервиса
ПространствоИмен = "http://www.fixinchik.ru/ClientsExchange";
ИмяСервиса = "_ОбменКонтрагентами";
ИмяПорта = "_ОбменКонтрагентамиSoap";

// 3. Явно задаем адрес, по которому будут уходить SOAP-запросы
// Именно здесь мы исправляем порт, если он в WSDL указан неверно
РеальныйАдресСервиса = "http://192.168.1.10:8002/base/ws/service.1cws";

// 4. Создаем прокси с указанием точки подключения
Прокси = Новый WSПрокси(Определение, ПространствоИмен, ИмяСервиса, ИмяПорта, РеальныйАдресСервиса);
Прокси.Пользователь = Логин;
Прокси.Пароль = Пароль;

Этот метод является наиболее предпочтительным, так как он не требует работы с временными файлами, не ломает импорты XSD-схем и полностью соответствует логике работы со стеком протоколов SOAP.

Решение 3: Настройка публикации на стороне веб-сервера

Если вы сами являетесь разработчиком сервиса на стороне 1С, лучше устранить причину, а не следствие. Проанализируем настройки IIS. Если веб-сервис работает на порту 8080, убедитесь, что в файле default.vrd в параметре base или в настройках сайта в IIS не указаны жесткие перенаправления, отрезающие порт.

Основные рекомендации для системного администратора:

  1. Если используется реверс-прокси (Nginx), необходимо пробрасывать заголовок Host: proxy_set_header Host $host:$server_port;.
  2. Проверьте привязки (Bindings) в консоли IIS. Если там указан конкретный IP или Hostname, 1С будет использовать их при формировании XML.
  3. В некоторых случаях помогает принудительное указание порта в строке подключения при публикации через консоль 1С (хотя штатно поле для порта в диалоге публикации отсутствует, порт можно добавить к имени хоста).

Советы по отладке

Если после всех манипуляций подключение все равно не устанавливается, рекомендуем выполнить следующие действия:

Подводя итог, можно сказать, что проблема нестандартного порта в WSDL — это классическая проблема инфраструктуры, которая легко обходится в 1С либо через временное сохранение файла с исправлением текста, либо (что лучше) через явное указание адреса точки подключения в конструкторе WSПрокси.

← На главную