При попытке добавить статическую WS-ссылку в дереве метаданных конфигурации или при динамическом создании объекта WSОпределения разработчики нередко сталкиваются с ситуацией, когда адрес WSDL-схемы без проблем открывается в обычном веб-браузере, но платформа 1С возвращает ошибку «Ошибка работы с Интернет: доступ запрещен (403). Forbidden». Разберем по шагам, почему возникает эта проблема, будет ли работать веб-сервис при сохранении WSDL-файла на локальный диск и какие существуют альтернативные способы интеграции.
Проанализируем типовой стек ошибки, возникающий при попытке прочитать удаленную схему:
Ошибка доступа к файлу 'https://example.com/api/soap/?WSDL'
по причине:
Ошибка работы с Интернет: доступ запрещен (403). Forbidden
Выясним причину, по которой веб-сервер отклоняет запрос платформы 1С, но успешно отдает данные браузеру:
/) в URL перед параметром ?WSDL, он возвращает HTTP-редирект (коды 301 или 302). Встроенный механизм загрузки статических WS-ссылок в 1С может терять завершающий слэш или некорректно обрабатывать перенаправление, что приводит к отказу в доступе со стороны сервера.WSОпределения встроенный язык не позволяет явно задать произвольные HTTP-заголовки (например, User-Agent, Authorization: Bearer или пользовательские cookies).Рассмотрим самый простой и надежный способ добавления WS-ссылки в конфигурацию, если сервер блокирует прямое скачивание схемы платформой. Разберем, как это сделать и почему данный подход гарантирует работоспособность сетевого обмена.
Многие разработчики сомневаются: если указать локальный путь к файлу при создании WS-ссылки, сможет ли 1С отправлять реальные запросы через интернет? Да, сервис будет работать полноценно. Файл WSDL необходим платформе исключительно на этапе инициализации для построения структуры типов XDTO, состава пакетов, методов и входных/выходных параметров. Конечный сетевой адрес (Endpoint), на который объект WSПрокси отправляет SOAP-запросы, берется из тега внутри самого XML-файла схемы:
<soap:address location="https://example.com/api/soap/service_endpoint"/>
Разберем порядок действий по шагам:
.wsdl или .xml.location внутри тега soap:address. В нем должен быть указан корректный удаленный URL веб-сервиса.Посмотрим на пример программного вызова операции через созданную статическую ссылку:
// Инициализация прокси на основе статической ссылки метаданных
Прокси = WSСсылки.ИнтеграцияСервис.СоздатьWSПрокси(
"http://example.com/namespace",
"ServiceName",
"ServiceSoapPort"
);
// Если сервис требует базовой авторизации
Прокси.Пользователь = "ЛогинСервиса";
Прокси.Пароль = "ПарольСервиса";
// Вызов требуемого метода веб-сервиса
Результат = Прокси.ПолучитьДанные(ПараметрЗапроса);
Если конфигурация не должна содержать статических ссылок в метаданных, а описание сервиса требуется загружать динамически в коде, обойдем блокировку 403 с помощью объекта HTTPСоединение.
Рассмотрим алгоритм: скачиваем WSDL-файл программно, явно передавая корректный заголовок User-Agent (эмулируя браузер), сохраняем ответ во временный файл и передаем его в конструктор WSОпределения.
// 1. Настройка соединения
Сервер = "is.topdelivery.ru";
ПутьКРесурсу = "/api/soap/w/2.0/?WSDL";
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение(Сервер, 443, , , , 30, ЗащищенноеСоединение);
// 2. Формирование запроса с установкой пользовательского заголовка
Запрос = Новый HTTPЗапрос(ПутьКРесурсу);
Запрос.Заголовки.Вставить("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");
// 3. Выполнение запроса и сохранение во временный файл
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("wsdl");
Ответ = Соединение.Получить(Запрос, ИмяВременногоФайла);
Если Ответ.КодСостояния = 200 Тогда
// 4. Создание WSОпределения из локального временного файла
Определения = Новый WSОпределения(ИмяВременногоФайла);
// 5. Создание WSПрокси для выполнения операций
WSПрокси = Новый WSПрокси(
Определения,
"http://is.topdelivery.ru/api/soap/w/2.0/",
"TopDelivery",
"TopDeliveryPort"
);
// Вызов методов сервиса
// Результат = WSПрокси.ИмяМетода();
// Удаление временного файла после инициализации
УдалитьФайлы(ИмяВременногоФайла);
Иначе
ВызватьИсключение "Не удалось получить WSDL. Код ответа: " + Ответ.КодСостояния;
КонецЕсли;
Проанализируем альтернативный вариант взаимодействия, который полностью исключает необходимость работы с объектами WS-ссылка и WSОпределения. Этот способ актуален, когда веб-сервер использует нестандартные схемы авторизации (например, OAuth, Bearer-токены, передачу ключей в заголовках), которые встроенный SOAP-клиент 1С не поддерживает.
В этом случае SOAP-пакет формируется вручную в виде XML-сообщения и передается методом POST через HTTPЗапрос:
// Формирование тела SOAP-конверта
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку("UTF-8");
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписьXML.ЗаписатьНачалоЭлемента("soapenv", "Envelope", "http://schemas.xmlsoap.org/soap/envelope/");
ЗаписьXML.ЗаписатьСоответствиеПрефикса("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
ЗаписьXML.ЗаписатьСоответствиеПрефикса("api", "http://is.topdelivery.ru/api/soap/w/2.0/");
ЗаписьXML.ЗаписатьНачалоЭлемента("soapenv", "Body", "http://schemas.xmlsoap.org/soap/envelope/");
ЗаписьXML.ЗаписатьНачалоЭлемента("api", "getOrderInfo", "http://is.topdelivery.ru/api/soap/w/2.0/");
ЗаписьXML.ЗаписатьНачалоЭлемента("orderId");
ЗаписьXML.ЗаписатьТекст("123456");
ЗаписьXML.ЗаписатьКонецЭлемента(); // orderId
ЗаписьXML.ЗаписатьКонецЭлемента(); // getOrderInfo
ЗаписьXML.ЗаписатьКонецЭлемента(); // Body
ЗаписьXML.ЗаписатьКонецЭлемента(); // Envelope
ТелоЗапроса = ЗаписьXML.Закрыть();
// Отправка SOAP-запроса через HTTPСоединение
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение("is.topdelivery.ru", 443, , , , 30, ЗащищенноеСоединение);
HTTPЗапрос = Новый HTTPЗапрос("/api/soap/w/2.0/");
HTTPЗапрос.Заголовки.Вставить("Content-Type", "text/xml; charset=utf-8");
HTTPЗапрос.Заголовки.Вставить("SOAPAction", "http://is.topdelivery.ru/api/soap/w/2.0/getOrderInfo");
HTTPЗапрос.Заголовки.Вставить("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапроса, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
Ответ = Соединение.ОтправитьДляОбработки(HTTPЗапрос);
Если Ответ.КодСостояния = 200 Тогда
СтрокаОтвета = Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
// Обработка XML-ответа через ЧтениеXML или ФабрикуXDTO
Иначе
ВызватьИсключение "Ошибка отправки SOAP-запроса: " + Ответ.КодСостояния;
КонецЕсли;
Подведем итог и определим, какой способ лучше применить в зависимости от архитектуры вашей системы:
WSПрокси.