Как подключиться к веб-сервису в 1С, если фактический адрес отличается от указанного в WSDL (работа через прокси)

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

Часто при интеграции систем мы сталкиваемся с ситуацией, когда веб-сервис находится за прокси-сервером или внутри защищенного контура с использованием NAT. В таких случаях 1С успешно загружает описание сервиса (WSDL) по одному адресу, но внутри самого XML-файла в секции soap:address location прописан внутренний, "нереальный" IP-адрес сервера (например, 192.168.x.x). При попытке выполнить вызов метода 1С обращается именно по этому внутреннему адресу и выдает ошибку подключения.

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

Причина возникновения проблемы

Проанализируем ситуацию: когда разработчик стороннего сервиса публикует WSDL, сервер автоматически генерирует адрес точки подключения, основываясь на своих локальных настройках. Если сервер не знает, что он находится за прокси, он впишет в описание свой локальный адрес. 1С, читая этот файл, строго следует стандарту SOAP и пытается отправить запрос именно туда, куда указывает тег location. Наша задача — заставить 1С игнорировать адрес из файла и использовать тот, который доступен нам физически.

Способ 1. Использование параметра Местоположение в WSПрокси

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

Рассмотрим пример для динамического подключения через WSОпределения:


// 1. Указываем адрес, где лежит WSDL (через прокси)
АдресWSDL = "http://10.10.XXX.XXX:10101/IntegrationService/IntegrationService.asmx?WSDL";

// 2. Создаем определения. Здесь 1С просто читает структуру методов.
Определения = Новый WSОпределения(АдресWSDL, ИмяПользователя, Пароль, ИнтернетПрокси);

// 3. А теперь самое важное: указываем РЕАЛЬНЫЙ адрес сервиса в 4-м параметре
// Даже если внутри WSDL написано 192.168.0.1, запрос уйдет на 10.70.XXX.XXX
РеальныйАдресСервиса = "http://10.70.XXX.XXX:10101/IntegrationService/IntegrationService.asmx";

Прокси = Новый WSПрокси(Определения, 
                        "http://tempuri.org/", // Пространство имен сервиса
                        "IntegrationService",   // Имя сервиса
                        "IntegrationServiceSoap", // Имя точки подключения
                        ИнтернетПрокси, 
                        Таймаут, 
                        ЗащищенноеСоединение, 
                        РеальныйАдресСервиса); // Вот он, переопределенный адрес!

Если вы используете WS-ссылку, добавленную в дерево конфигурации, принцип остается тем же. Метод СоздатьWSПрокси также принимает параметр Местоположение последним аргументом.

Способ 2. Программная модификация WSDL (динамический подход)

Если по какой-то причине первый способ не подходит (например, структура WSDL слишком сложная или адресов несколько), мы можем программно изменить текст описания перед тем, как скармливать его объекту WSОпределения. Это избавляет нас от необходимости вручную править файлы.

Разберем по шагам, как реализовать этот алгоритм:

  1. Скачиваем текст WSDL по сети через HTTPСоединение.
  2. Заменяем в тексте все вхождения ошибочного адреса на правильный с помощью функции СтрЗаменить.
  3. Сохраняем результат во временный файл или используем поток (для новых версий платформы).
  4. Создаем WSОпределения на основе измененного текста.

Посмотрим на пример реализации с временным файлом:


// Скачиваем WSDL как обычную строку
Соединение = Новый HTTPСоединение("10.10.XXX.XXX", 10101);
Запрос = Новый HTTPЗапрос("/IntegrationService/IntegrationService.asmx?WSDL");
Ответ = Соединение.Получить(Запрос);

Если Ответ.КодСостояния = 200 Тогда
    ТекстWSDL = Ответ.ПолучитьТелоКакСтроку();
    
    // Подменяем адрес. Важно заменить именно тот кусок, который мешает подключению.
    ТекстWSDL = СтрЗаменить(ТекстWSDL, "192.168.0.1:10101", "10.70.XXX.XXX:10101");
    
    // Сохраняем во временный файл
    ИмяФайла = ПолучитьИмяВременногоФайла("xml");
    ТекстовыйДокумент = Новый ТекстовыйДокумент;
    ТекстовыйДокумент.УстановитьТекст(ТекстWSDL);
    ТекстовыйДокумент.Записать(ИмяФайла, КодировкаТекста.UTF8);
    
    // Создаем определения из исправленного файла
    Определения = Новый WSОпределения(ИмяФайла);
    
    // Теперь создание прокси пройдет штатно, так как внутри XML уже верные адреса
    Прокси = Новый WSПрокси(Определения, "http://tempuri.org/", "IntegrationService", "IntegrationServiceSoap");
    
    // Не забываем удалить временный файл
    УдалитьФайлы(ИмяФайла);
КонецЕсли;

Способ 3. Использование объекта ИнтернетПрокси

Если проблема не только в адресе внутри WSDL, но и в том, что сама 1С не может "выйти" за пределы локальной сети без авторизации на прокси-сервере, нам необходимо правильно настроить объект ИнтернетПрокси. Многие совершают ошибку, просто создавая объект и не указывая в нем параметры для конкретных протоколов.

Проанализируем ситуацию настройки прокси:


ПроксиСервер = Новый ИнтернетПрокси;
// Нужно явно указать параметры для протокола http (или https)
ПроксиСервер.Установить("http", "10.10.XXX.XXX", 10101, "Пользователь", "Пароль");

// Теперь этот объект можно передавать в конструкторы
Определения = Новый WSОпределения(АдресWSDL, , , ПроксиСервер);

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

Нюансы работы с WS-ссылками в метаданных

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

Резюме и рекомендации

Выясним, какой метод лучше выбрать в вашей ситуации:

Таким образом, мы выяснили, что "сырость" платформы, о которой часто говорят на форумах, обычно заключается в недостаточном изучении параметров встроенных функций. Использование четвертого параметра конструктора WSПрокси полностью решает проблему работы через прокси-серверы и NAT без "костылей" с ручной правкой файлов.

← На главную