Как просмотреть заголовки ответа сервера в объекте WinHttp.WinHttpRequest.5.1 и почему отсутствует заголовок Location?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При интеграции 1С:Предприятия с внешними веб-сервисами и личными кабинетами через COM-объект WinHttp.WinHttpRequest.5.1 разработчики часто сталкиваются с ситуацией, когда прямое обращение к конкретному HTTP-заголовку (например, Location) вызывает ошибку времени выполнения. Разберем подробно, какими методами можно просмотреть все заголовки ответа, почему пропадает заголовок перенаправления и как правильно обрабатывать сетевые запросы.

1. Просмотр всех HTTP-заголовков ответа

Для чтения отдельного заголовка в объекте WinHttpRequest предназначен метод getResponseHeader(). Однако если запрашиваемого заголовка в ответе сервера нет, этот метод не возвращает пустую строку, а аварийно завершает работу с исключением. Чтобы увидеть полный список заголовков, возвращенных сервером, используем метод GetAllResponseHeaders().

Рассмотрим пример кода на платформе 1С:Предприятие 7.7, позволяющий безопасно получить и вывести все заголовки:


WinHttpReq = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
WinHttpReq.Open("POST", "https://service.fsrar.ru/auth/login", 0);
WinHttpReq.SetRequestHeader("Accept", "text/html, application/xhtml+xml, */*");
WinHttpReq.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded");

Попытка
    WinHttpReq.Send(СтрЗапр);
    
    // Получаем все заголовки ответа одной строкой
    ВсеЗаголовки = WinHttpReq.GetAllResponseHeaders();
    Сообщить("Заголовки ответа сервера:");
    Сообщить(ВсеЗаголовки);
Исключение
    Сообщить("Ошибка при отправке запроса или получении ответа: " + ОписаниеОшибки());
КонецПопытки;

Анализируя строку, возвращенную методом GetAllResponseHeaders(), можно точно определить, какие параметры передал сервер (например, Set-Cookie, Content-Type, Date, Server), и избежать ошибок при вызове отдельных свойств.

2. Почему отсутствует заголовок Location и как его перехватить

Выясним причину, по которой заголовок Location может отсутствовать в ответе, даже если при авторизации на сайте должен происходить переход на другую страницу. По умолчанию объект WinHttp.WinHttpRequest.5.1 автоматически следует по HTTP-редиректам (статусы 301, 302, 303, 307). В результате вы получаете ответ от конечной страницы с кодом состояния 200 OK, на которой заголовок Location уже не возвращается.

Чтобы перехватить сам статус перенаправления и извлечь URL из заголовка Location, необходимо отключить автоматический переход по редиректам с помощью специальной опции объекта.

Разберем по шагам отключение авторедиректа:

  1. Создаем экземпляр COM-объекта WinHttp.WinHttpRequest.5.1.
  2. Устанавливаем свойство Option(6) = 0 (параметр WinHttpRequestOption_EnableRedirects со значением 0 отключает автоматическое следование).
  3. Отправляем запрос методом Send().
  4. Проверяем код ответа через свойство Status. Если код равен 302 или 301, безопасно считываем заголовок Location через getResponseHeader("Location").

Посмотрим на пример реализации с отключением редиректов и безопасным чтением заголовка:


WinHttpReq = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
WinHttpReq.Open("POST", "https://service.fsrar.ru/auth/login", 0);

// Отключаем автоматический редирект (Option 6 = WinHttpRequestOption_EnableRedirects)
WinHttpReq.Option(6) = 0;

WinHttpReq.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded");

Попытка
    WinHttpReq.Send(СтрЗапр);
    
    // Проверяем код ответа
    Если (WinHttpReq.Status = 301) Или (WinHttpReq.Status = 302) Или (WinHttpReq.Status = 303) Тогда
        ПереходНаСайт = WinHttpReq.getResponseHeader("Location");
        Сообщить("URL перенаправления: " + ПереходНаСайт);
    Иначе
        Сообщить("Редирект не обнаружен. Код ответа: " + WinHttpReq.Status);
    КонецЕсли;
Исключение
    Сообщить("Не удалось выполнить запрос: " + ОписаниеОшибки());
КонецПопытки;

3. Важные нюансы настройки WinHttpRequest при авторизации

Проанализируем дополнительные технические детали, которые критически важны для стабильной работы с внешними порталами:

  1. Использование метода WaitForResponse(): Данный метод необходим только при асинхронном режиме работы (когда третий параметр метода Open установлен в 1 или Истина). При синхронном вызове (со значением 0) метод Send() блокирует выполнение до получения ответа, поэтому вызывать WaitForResponse() не требуется.
  2. Поддержка TLS 1.2: В устаревших операционных системах компонент WinHttp по умолчанию может использовать старые протоколы SSL. Для принудительного включения TLS 1.2 задайте опцию: WinHttpReq.Option(9) = 2048 (параметр WinHttpRequestOption_SecureProtocols).
  3. Сжатие данных (Accept-Encoding): Если указать заголовок Accept-Encoding: gzip, deflate, сервер вернет ответ в сжатом виде. Объект WinHttpRequest не распаковывает сжатый трафик автоматически, поэтому свойство ResponseText вернет нечитаемый бинарный поток. Если встроенной распаковки нет, не передавайте данный заголовок.
  4. Безопасное чтение любых заголовков: Любой вызов getResponseHeader() рекомендуется оборачивать в конструкцию Попытка ... Исключение ... КонецПопытки, чтобы исключить аварийное завершение работы модуля при отсутствии заголовка.
← На главную