Почему HTTP-сервис 1С 8.3 получает пустое тело запроса из 1С 7.7 и как это исправить?

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

При организации обмена данными между устаревшими и современными системами часто возникают труднообъяснимые ошибки. Одной из таких классических проблем, для отладки которой удобно использовать инструменты вроде Postman для 1С, является ситуация, когда запрос из 1С:Предприятие 7.7 успешно доходит до HTTP-сервиса 1С:Предприятие 8.3, метод вызывается, параметры URL считываются, но тело запроса (body) оказывается абсолютно пустым. Особенно часто это проявляется при переносе решения с файловой базы (под управлением Apache) на серверную (под управлением IIS).

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

Выясняем причину: почему Apache работает, а IIS — нет?

Рассмотрим ситуацию: на домашнем компьютере с Apache все работает отлично, а у клиента на Windows Server 2008 с IIS данные «теряются». Проанализируем техническую разницу между этими веб-серверами. Apache по умолчанию более лоялен к структуре HTTP-запроса, в то время как IIS (Internet Information Services) строго следует протоколам. Если веб-сервер IIS не получает четкого указания о типе контента или его длине, он может попросту не передать поток данных расширению 1С, считая запрос некорректным или завершенным.

Основные причины проблемы:

  1. Отсутствие заголовка Content-Type в запросе из 7.7.
  2. Несоответствие кодировок (1С 7.7 использует Windows-1251, а веб-сервисы ожидают UTF-8).
  3. Особенности авторизации WinHttp, когда первый запрос уходит пустым для проверки прав (401 Unauthorized).
  4. Ограничения фильтрации запросов в настройках самого IIS.

Шаг 1: Настройка заголовков запроса в 1С 7.7

Для начала проанализируем код отправки. В 1С 7.7 часто забывают про установку заголовков, полагаясь на автоматику (хотя для этих задач существуют и специализированные внешние компоненты). Однако для IIS крайне важно явно указать, что именно мы передаем. Если мы отправляем JSON, сервер должен об этом знать.

Добавим установку заголовка Content-Type. Это позволит IIS правильно идентифицировать входящий поток данных:


WinHttp = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
WinHttp.Open("POST", URL, 0);
// Указываем тип контента и кодировку
WinHttp.SetRequestHeader("Content-Type", "application/json; charset=utf-8");
WinHttp.SetCredentials(Логин, Пароль, 0);

Также полезно явно указывать заголовок Content-Length, хотя WinHttp обычно вычисляет его автоматически. Однако при работе с прокси-серверами или сложными конфигурациями IIS это может стать решающим фактором.

Шаг 2: Решение проблемы кодировки (UTF-8)

Это самый важный этап. 1С 7.7 — это ANSI-приложение. Когда мы пишем WinHttp.Send(ПакетJSON), передается строка в кодировке Windows-1251. На стороне 1С 8.3 метод Запрос.ПолучитьТелоКакСтроку() по умолчанию пытается интерпретировать данные как UTF-8. Если в строке встречаются кириллические символы, декодирование завершается ошибкой, и платформа возвращает пустую строку.

Для решения этой задачи воспользуемся объектом ADODB.Stream, чтобы принудительно конвертировать строку в массив байтов UTF-8 перед отправкой. Рассмотрим пример функции преобразования:


// Функция для преобразования строки в UTF-8
Функция ПреобразоватьВUTF8(Текст)
    Стрим = СоздатьОбъект("ADODB.Stream");
    Стрим.Type = 2; // adTypeText
    Стрим.Charset = "utf-8";
    Стрим.Open();
    Стрим.WriteText(Текст);
    Стрим.Position = 0;
    Стрим.Type = 1; // adTypeBinary
    // Возвращаем двоичные данные
    Результат = Стрим.Read();
    Возврат Результат;
КонецФункции

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


ДанныеДляОтправки = ПреобразоватьВUTF8(ПакетJSON);
WinHttp.Send(ДанныеДляОтправки);

Шаг 3: Настройка параметров WinHttp для корректной авторизации

При использовании метода SetCredentials объект WinHttp ведет себя специфически: он сначала отправляет «пустой» запрос без тела, чтобы получить от сервера ответ 401 и тип поддерживаемой авторизации (например, NTLM или Basic). После этого он отправляет запрос повторно уже с данными и заголовком авторизации. В некоторых конфигурациях IIS на серверных ОС (Windows Server 2008/2012) этот процесс может прерываться, особенно при использовании кириллицы в учетных данных.

Проанализируем настройку опций объекта. Мы можем разрешить автоматический редирект и обработку авторизации, установив соответствующие флаги:


WinHttp = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
// Опция 6 = WinHttpRequestOption_EnableRedirects
WinHttp.Option(6) = 1; 
WinHttp.Open("POST", URL, 0);

Шаг 4: Проверка настроек IIS (web.config)

Если программные методы не помогают, стоит заглянуть в настройки веб-сервера. В IIS существует модуль Request Filtering, который может блокировать тела запросов, если они превышают определенный размер, или если тип контента не разрешен.

Разберем, что нужно проверить в файле web.config, который находится в папке публикации вашей базы 1С:

  1. Найдите секцию requestFiltering.
  2. Проверьте параметр maxAllowedContentLength. Он определяет максимальный размер запроса в байтах.

Пример правильной настройки в web.config:


<system.webServer>
    <security>
        <requestFiltering>
            <requestLimits maxAllowedContentLength="104857600" /> 
        </requestFiltering>
    </security>
</system.webServer>

Здесь мы установили лимит в 100 Мб, что гарантирует прохождение даже больших JSON-пакетов.

Шаг 5: Корректировка HTTP-сервиса в 1С 8.3

На стороне приемника (8.3) также рекомендуется внести небольшие изменения для диагностики. Вместо метода Запрос.ПолучитьТелоКакСтроку() попробуйте сначала считать двоичные данные. Это позволит понять: данные не пришли вовсе или они пришли в «кривой» кодировке.

Проанализируем пример отладочного кода в 8.3:


Функция ОбслуживаниеЗапроса(Запрос)
    // Проверяем наличие данных в принципе
    ДвоичныеДанные = Запрос.ПолучитьТелоКакДвоичныеДанные();
    РазмерДанных = ДвоичныеДанные.Размер(); // Если > 0, значит данные дошли
    
    // Пытаемся прочитать как строку, явно указав кодировку
    СтрокаJSON = Запрос.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
    
    // Если СтрокаJSON пустая, но РазмерДанных > 0 - проблема в кодировке!
КонецФункции

Важный совет: В конфигураторе 1С 8.3 для метода HTTP-сервиса вместо значения «Любой» (Any) в поле «HTTP метод» лучше явно выбрать «POST». IIS корректнее сопоставляет обработчики, когда метод определен однозначно.

Резюме решения

Чтобы данные из 1С 7.7 стабильно попадали в 1С 8.3 под управлением IIS, необходимо:

Следуя этим шагам, мы обеспечим надежную работу интеграции и исключим потерю данных при передаче между разными поколениями платформы 1С.

← На главную