При интеграции 1С со сторонними веб-сервисами (например, SMS-шлюзами) в устаревшем коде нередко встречается связка COM-объектов Microsoft.XMLHTTP, MSScriptControl.ScriptControl и ADODB.Stream. На некоторых рабочих станциях такой код внезапно начинает аварийно завершаться ошибкой «Аргументы имеют неверный тип, выходят за пределы допустимого диапазона или вступают в конфликт друг с другом» на строке записи потока. Разберем причины этой проблемы и рассмотрим, как правильно переписать интеграцию с использованием встроенного в платформу 1С объекта HTTPСоединение.
Проанализируем, почему код на базе COM-объектов может стабильно работать на одном компьютере и давать сбой на другом:
ADODB.Stream.Write() ожидает на вход двоичный массив байтов. Если запрос через Microsoft.XMLHTTP завершился сбоем сети, таймаутом, блокировкой брандмауэра или сервер вернул пустой статус, свойство x.responseBody принимает значение VT_EMPTY или VT_NULL. Попытка передать пустое значение в s.Write() вызывает исключение времени выполнения.MSScriptControl.ScriptControl (файл msscript.ocx) существует исключительно в 32-разрядном исполнении. При запуске кода в 64-разрядном клиенте 1С или в фоновом задании на 64-разрядном сервере данный объект не может инициализироваться или приводит к ошибкам маршалинга типов.Microsoft.XMLHTTP использует системные настройки Internet Explorer конкретного пользователя Windows (версии TLS, кэш, сертификаты, системные параметры прокси-сервера). Различия в настройках учетных записей приводят к нестабильному поведению на разных рабочих местах.Для надежной работы платформы 1С рекомендуется полностью отказаться от внешних COM-библиотек и переписать логику на штатные объекты HTTPСоединение, HTTPЗапрос и HTTPОтвет.
При переходе важно учесть три ключевых нюанса:
+ в номере телефона), должны быть приведены к безопасному виду. Для этого в платформе 1С применяется функция КодироватьСтроку() с параметром СпособКодированияСтроки.КодировкаURL.Accept-Encoding: identity.HTTPСоединение.Получить() отправляет HTTP GET-запрос, а метод HTTPСоединение.ОтправитьДляОбработки() используется для отправки HTTP POST-запросов с телом.Посмотрим на пример выполнения GET-запроса с получением ответа в виде текста напрямую в переменную без использования временных файлов:
// 1. Формируем безопасные параметры запроса
ТекстСообщения = КодироватьСтроку("Здравствуйте! Ваш заказ готов.", СпособКодированияСтроки.КодировкаURL);
НомерТелефона = КодироватьСтроку("+79994450987", СпособКодированияСтроки.КодировкаURL);
АдресРесурса = "smw/aisms?action=post_sms"
+ "&user=" + СокрЛП(Константы.ЛогинСМС.Получить())
+ "&pass=" + СокрЛП(Константы.ПарольСМС.Получить())
+ "&sender=" + СокрЛП(Константы.ОтправительСМС.Получить())
+ "&target=" + НомерТелефона
+ "&message=" + ТекстСообщения;
// 2. Настраиваем заголовки
Заголовки = Новый Соответствие;
Заголовки.Вставить("Accept-Encoding", "identity"); // Запрещаем серверу сжимать ответ в gzip
// 3. Создаем соединение и отправляем запрос
HTTPСоединение = Новый HTTPСоединение(
СокрЛП(Константы.АдресСервераСМС.Получить()), // Хост сервера
, // Порт (по умолчанию)
СокрЛП(Константы.ЛогинСМС.Получить()), // Пользователь базовой аутентификации (если требуется)
СокрЛП(Константы.ПарольСМС.Получить()) // Пароль базовой аутентификации (если требуется)
);
HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса, Заголовки);
HTTPОтвет = HTTPСоединение.Получить(HTTPЗапрос);
// 4. Проверяем код состояния и читаем ответ
Если HTTPОтвет.КодСостояния = 200 Тогда
ТекстОтвета = HTTPОтвет.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
// Обработка полученного XML или JSON
Иначе
ВызватьИсключение "Ошибка HTTP-запроса: " + HTTPОтвет.КодСостояния;
КонецЕсли;
Если веб-сервер ожидает стандартный POST-запрос с типом содержимого application/x-www-form-urlencoded, параметры не следует передавать в адресной строке. Разберем по шагам, как поместить их в тело запроса:
// 1. Формируем тело POST-запроса
ТелоЗапроса = "action=post_sms"
+ "&user=" + КодироватьСтроку(СокрЛП(Константы.ЛогинСМС.Получить()), СпособКодированияСтроки.КодировкаURL)
+ "&pass=" + КодироватьСтроку(СокрЛП(Константы.ПарольСМС.Получить()), СпособКодированияСтроки.КодировкаURL)
+ "&sender=" + КодироватьСтроку(СокрЛП(Константы.ОтправительСМС.Получить()), СпособКодированияСтроки.КодировкаURL)
+ "&target=" + КодироватьСтроку("+79994450987", СпособКодированияСтроки.КодировкаURL)
+ "&message=" + КодироватьСтроку("Проверка отправки", СпособКодированияСтроки.КодировкаURL);
// 2. Устанавливаем заголовки
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
Заголовки.Вставить("Accept-Encoding", "identity");
// 3. Подготавливаем запрос
HTTPЗапрос = Новый HTTPЗапрос("smw/aisms", Заголовки);
HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапроса, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
// 4. Выполняем POST-запрос методом ОтправитьДляОбработки
HTTPСоединение = Новый HTTPСоединение(СокрЛП(Константы.АдресСервераСМС.Получить()));
HTTPОтвет = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
Если HTTPОтвет.КодСостояния = 200 Тогда
РезультатXML = HTTPОтвет.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
Иначе
ВызватьИсключение "Ошибка отправки POST-запроса: " + HTTPОтвет.КодСостояния;
КонецЕсли;
Использование встроенных механизмов платформы 1С гарантирует корректную работу в любых режимах запуска (как 32-разрядных, так и 64-разрядных), исключает зависимость от внешних COM-библиотек операционной системы и решает проблемы с кодировками и сетевыми сбоями.