При интеграции старых конфигураций на платформе 1С:Предприятие 7.7 с современными внешними веб-сервисами, интернет-магазинами или государственными информационными системами разработчики часто сталкиваются с зависанием запросов. На этапе отправки данных методом Send() система выдает критическую ошибку: «WinHttp.WinHttpRequest: Время ожидания операции истекло» (Timeout expired).
Внешне запрос выглядит абсолютно корректным, а аналогичные запросы через утилиту Postman, браузер или расширение RESTED выполняются моментально и возвращают нужные данные. Давайте подробно разберем, почему возникает эта проблема в среде 1С 7.7, проанализируем основные причины и пошагово реализуем их технические решения. В качестве альтернативы трудоёмкой отладке устаревшей системы часто применяется подбор решений для перехода с 1С 7.7 на актуальные конфигурации.
Самая распространенная причина таймаута в корпоративных сетях — отправка запросов «в обход» прокси-сервера. Браузеры и современные приложения автоматически подтягивают настройки прокси из операционной системы, тогда как объект WinHttp.WinHttpRequest.5.1 в 1С 7.7 по умолчанию пытается выполнить прямое подключение. Если прямого выхода в интернет у сервера или рабочей станции нет, запрос зависает и отваливается по таймауту.
Для решения этой проблемы применим метод SetProxy(). Рассмотрим пример настройки подключения:
// Создаем объект WinHttp
WinHttp = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
// Задаем кодировку ответа
WinHttp.Option(2, "utf-8");
// Инициализируем POST-запрос
WinHttp.Open("POST", URLАвторизация, 0);
// Явно настраиваем прокси-сервер.
// Параметр 2 означает ручную конфигурацию прокси.
// Второй параметр — адрес и порт вашего прокси-сервера.
// Третий параметр — список адресов-исключений (локальные ресурсы).
WinHttp.SetProxy(2, "192.168.1.100:8080", "*.local");
// Если ваш прокси-сервер требует авторизации, передаем учетные данные.
// Последний параметр "1" указывает, что авторизация предназначена именно для прокси.
WinHttp.SetCredentials("ПользовательПрокси", "ПарольПрокси", 1);
// Добавляем заголовки и отправляем запрос
WinHttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
WinHttp.Send(стрАвторизация);
ТекстОтвета = WinHttp.ResponseText;
Если в вашей сети используется прямое подключение без прокси-сервера, но системные настройки Windows пытаются его использовать, мы можем принудительно отключить использование прокси для объекта WinHttp, передав значение 1 в первом параметре:
// Принудительно отключаем использование прокси (прямое соединение)
WinHttp.SetProxy(1);
Современные веб-сервисы из соображений безопасности полностью блокируют входящие соединения по устаревшим протоколам SSL, TLS 1.0 и TLS 1.1. Платформа 1С 7.7 часто функционирует на устаревших версиях операционных систем (Windows XP, Windows Server 2008, Windows 7). Системная библиотека winhttp.dll в этих ОС по умолчанию не пытается инициировать соединение через современные протоколы TLS 1.2 или TLS 1.3.
В результате при вызове метода Send() на этапе рукопожатия (SSL Handshake) удаленный сервер просто сбрасывает или игнорирует пакеты, что приводит к таймауту. Чтобы исправить эту ситуацию, мы должны выполнить два шага.
Во-первых, обновим настройки операционной системы Windows. Нам потребуется установить официальный патч от Microsoft (например, KB3140245 для Windows 7) и включить поддержку протоколов TLS 1.2 в системном реестре Windows. Для этого создадим файлы реестра или вручную добавим параметр типа DWORD с именем DefaultSecureProtocols и значением 0x00000800 (для TLS 1.2) в следующие ветки:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp
Во-вторых, мы можем принудительно указать требуемую версию протокола шифрования непосредственно в программном коде 1С 7.7 с помощью опции безопасности под номером 9 (SecureProtocols):
WinHttp = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
// Устанавливаем принудительное использование протокола TLS 1.2
// Константа 2048 соответствует TLS 1.2.
// Если требуется также поддержка TLS 1.1, можно указать сумму флагов (2048 + 512 = 2560)
WinHttp.Option(9, 2048);
WinHttp.Open("POST", URLАвторизация, 0);
WinHttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
WinHttp.Send(стрАвторизация);
При тестировании интеграции с API разработчики часто используют тестовые сервера (Staging/Sandbox), на которых могут быть установлены самоподписанные SSL-сертификаты, либо сертификаты с истекшим сроком действия. В таких случаях объект WinHttpRequest прерывает выполнение операции из соображений безопасности, генерируя ошибку ожидания.
Проанализируем, как обойти эту проверку в среде разработки. Для этого задействуем опцию под номером 4 (SslErrorIgnoreFlags). Мы можем передать специальную маску флагов, которая заставит объект игнорировать любые проблемы с сертификатом сервера:
WinHttp = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
// Значение 13056 (или шестнадцатеричное 0x3300) принудительно игнорирует:
// - Неизвестный центр сертификации (Unknown CA)
// - Несоответствие имени хоста в сертификате (Host name mismatch)
// - Истекший срок действия сертификата (Expired certificate)
WinHttp.Option(4, 13056);
WinHttp.Open("POST", URLАвторизация, 0);
WinHttp.Send(стрАвторизация);
Важно: Применять игнорирование ошибок SSL рекомендуется исключительно на этапах разработки и отладки программного кода. В рабочих базах это может поставить под угрозу безопасность передаваемых данных. Для выполнения задач в системах без стабильного API предусмотрено создание программных роботов для выполнения сценариев без прямого доступа.
Платформа 1С 7.7 является исключительно однобайтовой системой и работает в кодировке Windows-1251 (ANSI). В то же время практически все современные веб-сервисы и REST API принимают данные строго в кодировке UTF-8.
Если в отправляемой строке JSON (например, в логине, пароле, наименовании товара или комментарии) содержатся символы кириллицы, сервер не сможет корректно распарсить поврежденный пакет. Некоторые серверные обработчики при получении некорректно кодированного JSON уходят в бесконечный цикл обработки или зависают, что возвращает нам ошибку таймаута на стороне 1С.
Установка опции WinHttp.Option(2, "utf-8") влияет только на интерпретацию входящего ответа, но не кодирует отправляемые данные. Использование устаревшего объекта MSScriptControl.ScriptControl часто вызывает ошибки на современных 64-битных операционных системах Windows. Наиболее надежным и производительным решением в 1С 7.7 является использование объекта ADODB.Stream для преобразования строки в двоичный поток UTF-8 перед отправкой.
Разберем готовый программный код для реализации этой схемы:
// Функция преобразует обычную строку 1С 7.7 в двоичные данные UTF-8
Функция ПолучитьПотокUTF8(ВходнаяСтрока)
Поток = СоздатьОбъект("ADODB.Stream");
Поток.Type = 2; // Переключаем в текстовый режим
Поток.Charset = "utf-8";
Поток.Open();
Поток.WriteText(ВходнаяСтрока);
// Сбрасываем позицию в начало потока
Поток.Position = 0;
// Переводим поток в бинарный режим для чтения сырых байтов
Поток.Type = 1;
// Возвращаем двоичные данные UTF-8
Возврат Поток.Read();
КонецФункции
// Пример отправки запроса с конвертацией данных
Процедура ВыполнитьЗапрос()
К = Симв(34); // Символ кавычки
стрАвторизация = "{" + К + "email" + К + ":" + К + Логин + К + "," + К + "password" + К + ":" + К + Пароль + К + "}";
// Преобразуем JSON-строку в массив байтов UTF-8
ТелоЗапросаUTF8 = ПолучитьПотокUTF8(стрАвторизация);
WinHttp = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
WinHttp.Open("POST", URLАвторизация, 0);
// Задаем заголовок типа контента с указанием кодировки UTF-8
WinHttp.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
// Передаем в метод Send подготовленный бинарный поток
WinHttp.Send(ТелоЗапросаUTF8);
ТекстОтвета = WinHttp.ResponseText;
Сообщить(ТекстОтвета);
КонецПроцедуры
Если операционная система, на которой развернута 1С 7.7, критически устарела и не поддается обновлению, или если системные ограничения безопасности не позволяют настроить WinHttpRequest, отличной альтернативой станет использование внешней консольной утилиты curl.
Утилита curl содержит собственные независимые библиотеки шифрования, поддерживает все современные стандарты (включая TLS 1.3 и HTTP/2) и легко запускается из кода 1С 7.7 через объект командной оболочки WScript.Shell.
Посмотрим на пример практической реализации отправки запроса через curl:
// Создаем объект для выполнения команд операционной системы
Шелл = СоздатьОбъект("WScript.Shell");
// Имя временного файла, куда запишем ответ сервера
ФайлОтвета = КаталогВременныхФайлов() + "api_response.json";
// Формируем командную строку для утилиты curl
// Параметр -k отключает строгую проверку SSL (аналог Option 4 в WinHttp)
// Параметр -X указывает метод запроса (POST)
// Параметр -H задает заголовки
// Параметр -d задает отправляемые данные JSON
// Символ ">" перенаправляет поток вывода в текстовый файл
Команда = "curl -k -X POST -H ""Content-Type: application/json"" -d ""{\""email\"":\""api\"",\""password\"":\""111\""}"" " + URLАвторизация + " > """ + ФайлОтвета + """";
// Выполняем команду в скрытом окне (0) с ожиданием завершения процесса (1)
Шелл.Run("cmd.exe /c " + Команда, 0, 1);
// Читаем полученный ответ из файла
Текст = СоздатьОбъект("Текст");
Текст.Открыть(ФайлОтвета);
ТекстОтвета = "";
Для Ном = 1 По Текст.КоличествоСтрок() Цикл
ТекстОтвета = ТекстОтвета + Текст.ПолучитьСтроку(Ном) + РазделительСтрок;
КонецЦикла;
// Удаляем временный файл после обработки данных
ФС.УдалитьФайл(ФайлОтвета);
Сообщить("Ответ от сервера: " + ТекстОтвета);