Почему HTTP-сервис в 1С возвращает старые данные и как правильно настроить кэширование?

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

При разработке и эксплуатации HTTP-сервисов на платформе 1С:Предприятие программисты часто сталкиваются с ситуацией, когда при повторном вызове метода GET система возвращает старый ответ, хотя данные в информационной базе уже изменились. Особенно сбивает с толку тот факт, что в Журнале Регистрации 1С повторный запрос может даже не отображаться. Это явный признак того, что запрос «оседает» где-то на промежуточном уровне. В этой статье мы подробно разберем, почему это происходит, как работают механизмы кэширования и что нужно сделать, чтобы гарантированно получать актуальные данные.

Разберем механику проблемы: почему 1С не видит запрос?

Когда внешняя система (например, конфигурация 1С 7.7, 10.3 или стороннее приложение) обращается к HTTP-сервису 1С, запрос проходит через несколько этапов. Если запрос типа GET выполняется повторно с теми же параметрами, ответ может быть возвращен из кэша. Существует три основных места, где может происходить кэширование:

  1. Клиентская сторона (библиотеки ОС): Платформа 1С под Windows использует системные компоненты WinInet или WinHTTP. Они могут сохранять ответы в локальном кэше компьютера, и запрос даже не покинет пределы вашей сетевой карты.
  2. Промежуточные узлы (Прокси-серверы): Различные сетевые экраны, антивирусы и прокси-серверы могут перехватывать запросы и отдавать «сохраненку» для экономии трафика.
  3. Веб-сервер (IIS или Apache): Это наиболее частая причина. Веб-сервер IIS имеет мощный механизм Output Caching (кэширование вывода), который запоминает ответ динамического приложения (которым является 1С) и отдает его мгновенно, не нагружая рабочий процесс w3wp.exe и не заходя в саму базу 1С.

Проанализируем ситуацию: если в Журнале Регистрации нет записи о входящем соединении, значит, запрос «застрял» на веб-сервере или клиенте. Выясним, как с этим бороться.

Решение 1. Программное управление заголовками в 1С

Согласно протоколу HTTP, сервер может управлять поведением кэша с помощью специальных заголовков в ответе. Если мы хотим сказать всем посредникам и клиенту, что данные нельзя кэшировать, нам нужно правильно сформировать HTTPСервисОтвет.

Рассмотрим пример кода на стороне сервера (в модуле HTTP-сервиса), который принудительно отключает кэширование:


Ответ = Новый HTTPСервисОтвет(200);

// Указываем, что контент динамический
Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");

// Запрещаем кэширование всеми доступными способами
// no-store: не сохранять в кэш вообще
// no-cache: обязательно проверять свежесть на сервере
// must-revalidate: если кэш устарел, обязательно переспросить сервер
Ответ.Заголовки.Вставить("Cache-Control", "no-store, no-cache, must-revalidate");

// Для старых прокси-серверов (HTTP/1.0)
Ответ.Заголовки.Вставить("Pragma", "no-cache");

// Устанавливаем дату истечения в прошлом (1970 год)
Ответ.Заголовки.Вставить("Expires", "Thu, 01 Jan 1970 00:00:00 GMT");

ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
// Формируем данные
Данные = Новый Структура("Результат, ТекущееВремя", "ОК", ТекущаяДата());
ЗаписатьJSON(ЗаписьJSON, Данные);

Ответ.УстановитьТелоИзСтроки(ЗаписьJSON.Закрыть());
Возврат Ответ;

Важный нюанс: Иногда веб-сервер IIS может игнорировать заголовки, добавленные из кода 1С, или вырезать их при определенных настройках безопасности. Поэтому, если программный метод не помог, переходим к настройкам сервера.

Решение 2. Настройка Output Caching на стороне IIS

Если вы используете Internet Information Services (IIS), посмотрите на настройки «Кэширование вывода» (Output Caching). По умолчанию IIS может пытаться оптимизировать работу, кэшируя ответы от расширений .dll. Поскольку публикация 1С работает через isapi_1c8.dll (или wsapvr.dll), IIS может ошибочно считать ответы статичными.

Выполним следующие шаги для отключения кэша в консоли IIS:

  1. Откройте Диспетчер служб IIS.
  2. Выберите вашу опубликованную информационную базу в дереве слева.
  3. В центральной части окна найдите раздел «Кэширование вывода» (Output Caching).
  4. Проверьте наличие правил. Если там есть правила для расширения * или для путей вашего сервиса, их стоит удалить или изменить.
  5. В правой панели действий выберите «Изменить параметры кэша...» и убедитесь, что кэширование вывода отключено глобально для этого приложения.

Также можно внести изменения напрямую в файл web.config вашей публикации, добавив в секцию <system.webServer> следующую строку:


<configuration>
  <system.webServer>
    <caching enabled="false" />
  </system.webServer>
</configuration>

Это гарантирует, что IIS не будет пытаться сохранить ответ в своей памяти.

Решение 3. Использование метода POST вместо GET

В архитектуре REST метод GET считается «идемпотентным» и «безопасным», что по умолчанию дает право всем сетевым узлам кэшировать его результат. Метод POST, напротив, предназначен для изменения состояния сервера, и его ответы по спецификации RFC практически никогда не кэшируются автоматически.

Если ваша задача позволяет отойти от строгих канонов REST и вам нужно гарантированно получать свежие данные без настройки веб-сервера, попробуйте просто заменить тип запроса. Рассмотрим, как изменится код вызова в 1С (клиентская часть):


// Вместо .Получить() используем .ОтправитьДляОбработки()
HTTPСоединение = Новый HTTPСоединение(Сервер, , , , , 5);
HTTPЗапрос = Новый HTTPЗапрос("/hs/my_service/v1/get_data");
// Даже если тело пустое, POST заставит сервер отработать честно
HTTPЗапрос.УстановитьТелоИзСтроки("{}"); 

HTTPОтвет = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);

Это решение часто называют «костылем», но в корпоративных сетях со сложной структурой прокси-серверов оно является самым надежным.

Решение 4. Метод Cache Busting (добавление уникального ключа)

Если вы обязаны использовать GET, но кэш все равно мешает, применим проверенный метод из веб-разработки — добавление в строку запроса изменяющегося параметра, который сервер 1С будет просто игнорировать.

Посмотрим на пример формирования URL:


// Добавляем к адресу случайное число или метку времени
УникальныйКлюч = Формат(ТекущаяУниверсальнаяДатаВМиллисекундах(), "ЧГ=0");
АдресРесурса = "/hs/my_service/v1/get_data?nocache=" + УникальныйКлюч;

HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса);
HTTPОтвет = HTTPСоединение.Получить(HTTPЗапрос);

Для любого кэширующего прокси-сервера или самого IIS запрос с новым параметром в URL — это совершенно новый запрос. Он обязан передать его в 1С, так как не имеет в своей базе данных ответа для такого точного адреса. Это самый простой и эффективный способ «пробить» любой кэш без прав администратора на сервере.

Итоги и рекомендации

Подведем итог нашему исследованию. Если ваш HTTP-сервис в 1С возвращает старые данные, действуйте по алгоритму:

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

← На главную