Как исправить ошибки 301 и 500 при отправке SOAP-запроса из 1С на сервер

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

При интеграции систем 1С:Предприятие с внешними веб-сервисами по протоколу SOAP программисты часто сталкиваются с неочевидным поведением сервера. Ошибки с кодами 301 Moved Permanently и 500 Internal Server Error могут поставить в тупик, так как их причины кроются как в настройках самого соединения, так и в структуре передаваемого XML-пакета. В этой статье мы подробно разберем, как правильно настроить HTTPСоединение, сформировать заголовки и тело запроса, чтобы успешно передать данные.

Разбираем причину ошибки 301 (Moved Permanently)

Ошибка с кодом 301 означает, что запрашиваемый ресурс был окончательно перемещен на другой адрес. В контексте работы с 1С и веб-серверами (например, под управлением nginx) это чаще всего происходит из-за отсутствия завершающего слеша в пути запроса.

Проанализируем ситуацию: если вы указываете путь /api/soap, сервер может автоматически перенаправлять вас на /api/soap/. Рассмотрим, как это выглядит в коде 1С, который вызывает проблему:

HTTPЗапрос = Новый HTTPЗапрос("/api/soap", ЗаголовокЗапросаHTTP);

В этом случае 1С получает ответ с кодом 301. Важно понимать, что объект HTTPСоединение в 1С при использовании метода Получить() или ОтправитьДляОбработки() не всегда автоматически следует за редиректом, особенно если это касается безопасности или изменения типа запроса. Чтобы исправить это, достаточно внимательно изучить заголовок Location в ответе сервера. Если там указан адрес с закрывающим слешем, необходимо просто поправить строку пути в вашем HTTPЗапрос.

Исправленный вариант будет выглядеть так:

HTTPЗапрос = Новый HTTPЗапрос("/api/soap/", ЗаголовокЗапросаHTTP);

Переход от GET к POST и настройка заголовков

Протокол SOAP требует использования метода POST. Часто разработчики на этапе отладки пытаются вызвать HTTPСоединение.Получить(HTTPЗапрос), что соответствует методу GET. Сервер в ответ на это может выдать ошибку RequestNotAllowed или потребовать правильный Content-Type.

Для корректной работы SOAP необходимо использовать метод ОтправитьДляОбработки(). Также критически важно правильно заполнить коллекцию Соответствие для заголовков запроса. Основным заголовком для SOAP 1.1 является Content-Type со значением text/xml; charset=utf-8. Однако многие современные системы, такие как Verme WFM, также требуют специфический заголовок SOAPAction.

Рассмотрим пример настройки заголовков:


ЗаголовокЗапросаHTTP = Новый Соответствие;
ЗаголовокЗапросаHTTP.Вставить("Content-Type", "text/xml; charset=utf-8");
// Для SOAP 1.1 обязательно указываем имя вызываемого метода
ЗаголовокЗапросаHTTP.Вставить("SOAPAction", "setEmployee"); 

Формирование тела SOAP-запроса

Когда проблема с редиректом решена, может возникнуть ошибка 500 Internal Server Error. Это "общая" ошибка сервера, которая в случае с SOAP почти всегда означает, что сервер не смог распарсить ваш XML или переданные данные не прошли валидацию.

Проанализируем типичные ошибки при ручной сборке XML-строки. В 1С часто используют конкатенацию строк, что чревато незакрытыми тегами или наличием спецсимволов в данных. Посмотрим на пример структуры SOAP Envelope:


СтрокаXML = "
|<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:v1=""http://verme.ru/api/v1"">
|   <soapenv:Header/>
|   <soapenv:Body>
|      <v1:setEmployee>
|         <login>" + Логин + "</login>
|         <password>" + Пароль + "</password>
|         <employee>
|            <employeeId>" + employeeId + "</employeeId>
|            <name>" + name + "</name>
|         </employee>
|      </v1:setEmployee>
|   </soapenv:Body>
|</soapenv:Envelope>";

Важные моменты при формировании XML:

  1. Корректность тегов: Убедитесь, что каждый открытый тег (например, <soapenv:Envelope>) имеет соответствующий закрывающий тег. В коде из первого сообщения темы была закомментирована строка, что привело к нарушению структуры XML.
  2. Экранирование символов: Если в переменных name или jobcode встретятся символы амперсанда (&), кавычек или скобок, XML станет невалидным. Профессиональнее использовать объект ЗаписьXML для автоматического экранирования.
  3. Формат даты: Серверы SOAP крайне чувствительны к форматам. Вместо стандартного формата даты 1С используйте строку вида YYYY-MM-DD или YYYY-MM-DDTHH:MM:SS в зависимости от требований WSDL.

Использование защищенного соединения (SSL)

Если сервер работает по протоколу HTTPS, необходимо инициализировать объект ЗащищенноеСоединениеOpenSSL. Без этого 1С не сможет установить рукопожатие (handshake) с сервером, использующим современные сертификаты. В параметрах конструктора HTTPСоединение этот объект передается последним.


Соединение = Новый HTTPСоединение(
    "ekonika-test.verme.ru", // Хост
    443,                     // Порт для HTTPS
    Логин, 
    Пароль, 
    , 
    60, 
    Новый ЗащищенноеСоединениеOpenSSL()
);

Как отлаживать такие запросы?

Если вы исправили адрес и заголовки, но сервер продолжает возвращать ошибку 500, воспользуйтесь следующими инструментами:

  1. Fiddler или Charles: Эти прокси-серверы позволяют перехватить запрос из 1С и увидеть "сырой" текст, который уходит на сервер. Вы сможете сравнить его с рабочим примером из документации к API.
  2. SoapUI: Это эталонное средство для тестирования SOAP. Попробуйте отправить запрос через SoapUI. Если там он проходит успешно, просто скопируйте структуру XML и заголовки в код 1С.
  3. Чтение тела ответа: При ошибке 500 сервер часто присылает детальное описание проблемы в формате XML (так называемый soapenv:Fault). Всегда анализируйте результат методом Результат.ПолучитьТелоКакСтроку(). Там может быть прямо указано, какой параметр передан неверно.

Проанализировав ситуацию с редиректами и форматом XML, мы выяснили, что ключ к успеху кроется в точном соблюдении спецификации сервера: правильный путь со слешем, наличие SOAPAction и валидный XML без синтаксических ошибок. Рассмотрим эти рекомендации как обязательный чек-лист при любой интеграции через HTTPСоединение.

← На главную