Как правильно отправить запрос к веб-сервису и получить ответ в 1С

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

При интеграции сторонних систем с базой данных 1С программисты часто сталкиваются с необходимостью отправки запросов к сторонним веб-сервисам. Протокол SOAP (Simple Object Access Protocol) остается одним из самых распространенных стандартов обмена данными. Однако при попытке отправить SOAP-запрос вручную разработчики нередко совершают типичные ошибки, из-за которых вместо ожидаемого структурированного XML-ответа сервер возвращает обычный HTML-код главной страницы сайта.

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

Выясняем причину: почему сервер возвращает главную страницу?

Давайте проанализируем типичный пример кода, при котором вместо XML-ответа возвращается главная страница сайта:


HTTP_Соединение = Новый HTTPСоединение("testserver.ru", , , , , , Новый ЗащищенноеСоединениеOpenSSL);
    
HTTP_Запрос = Новый HTTPЗапрос;    
HTTP_Запрос.УстановитьТелоИзСтроки(ТекстЗапроса, КодировкаТекста.UTF8);    
HTTP_Ответ = HTTP_Соединение.ОтправитьДляОбработки(HTTP_Запрос);
ТекстОтвета = HTTP_Ответ.ПолучитьТелоКакСтроку();

Основная ошибка здесь кроется в строке создания объекта HTTPЗапрос. В конструкторе этого объекта не указан путь к конкретному ресурсу (адрес эндпоинта веб-сервиса). Когда мы пишем Новый HTTPЗапрос без параметров, платформа по умолчанию обращается к корню сайта (путь /). Сервер принимает этот запрос и, не понимая, к какому веб-сервису идет обращение, просто возвращает стандартную стартовую страницу (индексный файл).

Вторая проблема заключается в отсутствии обязательных HTTP-заголовков. Протокол SOAP требует строгого форматирования заголовков запроса, чтобы веб-сервер мог корректно идентифицировать и обработать входящий XML-пакет.

Решение №1: Настройка ручной отправки SOAP-запроса через HTTPСоединение

Если вам по каким-то причинам необходимо отправлять SOAP-конверт вручную (например, при сложной нестандартной авторизации или ограничениях сетевой безопасности), необходимо исправить структуру запроса.

Выполним настройку по шагам:

  1. Укажем путь к ресурсу. В конструкторе HTTPЗапрос обязательно передаем относительный путь к файлу публикации веб-сервиса (например, /api/service.asmx или /ws/MyService.1cws).
  2. Используем метод POST. По спецификации SOAP запросы должны отправляться методом POST. Для этого в 1С используется метод соединения ОтправитьДляОбработки().
  3. Добавим заголовок Content-Type. Сервер должен знать, что мы передаем XML-данные. Для спецификации SOAP 1.1 используется заголовок text/xml; charset=utf-8, а для SOAP 1.2 — application/soap+xml; charset=utf-8.
  4. Добавим заголовок SOAPAction. Этот заголовок указывает серверу, какую именно операцию (метод) мы хотим выполнить. Значение заголовка можно узнать из документации к сервису или его WSDL-схемы. Если сервер не требует точного указания действия, заголовок все равно должен присутствовать, но оставаться пустым.

Рассмотрим пример исправленного и полностью работоспособного кода:


// Создаем защищенное SSL-соединение
SSLСоединение = Новый ЗащищенноеСоединениеOpenSSL();
HTTP_Соединение = Новый HTTPСоединение("testserver.ru", , , , , , SSLСоединение);

// Обязательно указываем относительный путь к веб-сервису
АдресРесурса = "/api/service.asmx";
HTTP_Запрос = Новый HTTPЗапрос(АдресРесурса);

// Устанавливаем обязательные заголовки для SOAP-запроса
HTTP_Запрос.Заголовки.Вставить("Content-Type", "text/xml; charset=utf-8");
HTTP_Запрос.Заголовки.Вставить("SOAPAction", "http://testserver.ru/QueryDocuments"); // Имя операции

// Помещаем XML-конверт в тело запроса
HTTP_Запрос.УстановитьТелоИзСтроки(ТекстЗапроса, КодировкаТекста.UTF8);

Попытка
    // Отправляем POST-запрос на сервер
    HTTP_Ответ = HTTP_Соединение.ОтправитьДляОбработки(HTTP_Запрос);
    
    Если HTTP_Ответ.КодСостояния = 200 Тогда
        ТекстОтвета = HTTP_Ответ.ПолучитьТелоКакСтроку();
        // Здесь пишем код для парсинга полученного XML-ответа
    Иначе
        ВызватьИсключение "Ошибка сервера: " + HTTP_Ответ.КодСостояния;
    КонецЕсли;
Исключение
    Сообщить("Не удалось отправить запрос: " + ОписаниеОшибки());
КонецПопытки;

Решение №2 (Рекомендуемое): Использование штатных механизмов WS-прокси

Ручная сборка XML-строки запроса и последующий разбор XML-ответа — это трудоемкий и нестабильный процесс. При любом изменении структуры данных на стороннем сервисе ваш код может сломаться. Платформа 1С предлагает мощный встроенный инструмент для работы с SOAP-сервисами — механизм WS-ссылок и объект WSПрокси.

Для интеграции нам понадобится только ссылка на описание веб-сервиса — WSDL-схема (обычно она имеет вид https://testserver.ru/service.asmx?wsdl).

Давайте разберем, как динамически подключиться к стороннему сервису без изменения метаданных конфигурации:


// Шаг 1. Инициализируем защищенное соединение для работы по HTTPS
SSL = Новый ЗащищенноеСоединениеOpenSSL();

// Шаг 2. Загружаем WSDL-схему стороннего сервиса
МестоположениеWSDL = "https://testserver.ru/service.asmx?wsdl";

Попытка
    // Объект WSОпределения считывает структуру сервиса, его методы и типы данных
    Определения = Новый WSОпределения(МестоположениеWSDL, , , , , SSL);
Исключение
    Сообщить("Ошибка получения WSDL-схемы: " + ОписаниеОшибки());
    Возврат;
КонецПопытки;

// Шаг 3. Задаем параметры подключения из документации стороннего сервиса
ПространствоИмен = "http://testserver.ru/"; // URI пространства имен
ИмяСервиса       = "DocumentService";       // Имя сервиса в WSDL
ИмяТочки         = "DocumentServiceSoap";   // Точка подключения в WSDL

// Шаг 4. Создаем объект WSПрокси
Прокси = Новый WSПрокси(Определения, ПространствоИмен, ИмяСервиса, ИмяТочки, , SSL);

// Если сервис требует авторизации (Basic Authentication)
Прокси.Пользователь = "MyName";
Прокси.Пароль       = "MyPassword";

// Шаг 5. Вызываем удаленный метод как обычную функцию 1С!
Попытка
    // Метод QueryDocuments вызовется автоматически, платформа сама сформирует XML
    Результат = Прокси.QueryDocuments("MyName", "MyPassword");
    
    // Результат возвращается в виде типизированного объекта XDTO
    // Обрабатываем полученные данные
    Для Каждого Документ Из Результат.СписокДокументов Цикл
        Сообщить("Получен документ №: " + Документ.Номер);
    КонецЦикла;
Исключение
    Сообщить("Ошибка при вызове метода сервиса: " + ОписаниеОшибки());
КонецПопытки;

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

Рекомендация по отладке внешних веб-сервисов

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

Достаточно импортировать в SoapUI адрес WSDL-схемы стороннего сервиса. Программа автоматически сгенерирует структуру правильного SOAP-запроса, укажет нужный SOAPAction и позволит быстро проверить авторизацию. Убедившись, что во внешнем клиенте получен успешный ответ со списком документов, вы сможете безошибочно перенести параметры подключения и структуру запроса в среду разработки 1С.

← На главную